546   MySQL

一,问题:
MySQL事物操作的过程中,并发的场景下,经常是遇到以下问题:
1,可以读取未提交的数据的情况下,产生脏读(dirty reads)
事物A在修改了数据,但是尚未提交;这时事物B去读取这些已经修改的数据;但事物A因为某种原因回滚即rollback了,那么事物B读到数据最终并没提交,根本不存在,所以导致了脏读;

2,只能读取已提交的数据的情况下,产生不可重复读(non-repeatable reads)
事物B在查询了一次数据,然后继续执行其他操作;这时事物A修改了这些数据,并且提交了;事物B后来第二次去读这些数据,发现跟之前第一次读到数据不一样;这时因为事物A修改并提交了这些数据。所以数据不可重复读了。

3,同一事物开始之后读取的数据都不变,产生幻读(phantom read)
事物A开始读取数据,发现用户ID=4不存在;这时事物B插入一条用户ID=4的记录,并且提交了;然后事物A执行同样的插入,结果提示用户ID=4已经存在,这时事物A再去读取数据时,发现用户ID=4依然不存在,因为同一事物开始之后读取的数据都不变。这就导致了数据幻读

 

二,隔离级别

MySQL的隔离级别,以及会产生的问题

隔离解别 脏读 不可重复读 幻读
Read Uncommitted/可读取未提交 Y Y Y
Read Committed/只读取已提交 N Y Y
Repeatable Read(default)/可重复读 N N Y
Serializable/串行化 N N N

 

1,查看MySQL全局隔离级别和当前会话隔离级别

mysql> select @@global.tx_isolation,@@tx_isolation;
+-----------------------+-----------------+
| @@global.tx_isolation | @@tx_isolation  |
+-----------------------+-----------------+
| REPEATABLE-READ       | REPEATABLE-READ |
+-----------------------+-----------------+
1 row in set (0.00 sec)

2,修改MySQL隔离级别

mysql> set session tx_isolation='read-uncommitted';
Query OK, 0 rows affected (0.00 sec)

mysql> set global tx_isolation='read-uncommitted';  
Query OK, 0 rows affected (0.00 sec)

mysql> select @@global.tx_isolation,@@tx_isolation;
+-----------------------+------------------+
| @@global.tx_isolation | @@tx_isolation   |
+-----------------------+------------------+
| READ-UNCOMMITTED      | READ-UNCOMMITTED |
+-----------------------+------------------+
1 row in set (0.00 sec)

mysql> 



Leave a Reply

Your email address will not be published. Required fields are marked *