二 最详细MySQL事务隔离级别及原理讲解!( 二 )


二 最详细MySQL事务隔离级别及原理讲解!

文章插图
 
如图,证明两个事务在更新时发生了排他锁竞争 。
脏读(DIRTY READ)那么未提交读会产生什么问题?刚才的例子依旧说明了,发生了脏读 。如图:
二 最详细MySQL事务隔离级别及原理讲解!

文章插图
 
右边事务读取到了左边事务更改后的数据 a=11,但左边事务还未提交 。
我们依旧给出脏读的定义:
An operation that retrieves unreliable data, data that was updated by another transaction but not yet committed. It is only possible with the isolation level known as read uncommitted.
检索不可靠数据的操作,该数据是由另一个事务更新但尚未提交的数据 。只有在隔离级别称为未提交读的情况下才有可能 。
划重点!读出来的数据不可靠,是可以被其他事务修改后未提交的数据 。脏读只可能出现在未提交读情况下 。
2、读已提交(READ_COMMITTED)
读已提交和读未提交最大的区别如名字所说,可以读到另一个事务已提交读数据 。官方定义如下:
An isolation level that uses a locking strategy that relaxes some of the protection between transactions, in the interest of performance. Transactions cannot see uncommitted data from other transactions, but they can see data that is committed by another transaction after the current transaction started. Thus, a transaction never sees any bad data, but the data that it does see may depend to some extent on the timing of other transactions.
事务无法看到来自其他事务的未提交的数据,但是它们可以看到在当前事务开始后另一个事务提交的数据 。因此,一个事务永远不会看到任何不良数据,但是它所看到的数据可能在某种程度上取决于其他事务的时间安排 。
实验前,更改数据库隔离级别为RC 。
mysql> set session transaction isolation level read committed;Query OK, 0 rows affected (0.01 sec)mysql> SELECT @@tx_isolation;+----------------+| @@tx_isolation |+----------------+| READ-COMMITTED |+----------------+1 row in set, 1 warning (0.00 sec)事务A
事务B
二 最详细MySQL事务隔离级别及原理讲解!

文章插图
 

二 最详细MySQL事务隔离级别及原理讲解!

文章插图
 

二 最详细MySQL事务隔离级别及原理讲解!

文章插图
 

二 最详细MySQL事务隔离级别及原理讲解!

文章插图
 
脏读被解决
二 最详细MySQL事务隔离级别及原理讲解!

文章插图
 

二 最详细MySQL事务隔离级别及原理讲解!

文章插图
 

二 最详细MySQL事务隔离级别及原理讲解!

文章插图
 
不可重复读出现
如上表AB事务可知,在B事务更改数据 a=11 且事务未提交时,A事务读取到的还是旧数据 a=9,可见RC隔离级别很好的解决了脏读的问题 。
但是紧接着在B事务提交后,A事务再次读取数据,a=11 。在同一事务中两次查询出现了结果不一样的情况,这就是不可重复读 。官方定义:
non-repeatable read:The situation when a query retrieves data, and a later query within the same transaction retrieves what should be the same data, but the queries return different results (changed by another transaction committing in the meantime).
查询检索数据,而同一事务中的前后查询检索应为相同的数据,但实际查询返回不同的结果(数据同时被其他提交的事务更改) 。
很关键的一点,不可重复读是同一事务前后同样的查询返回了不同的数据!一定有人有这样的疑惑,那脏读不也是前后不一致吗,怎么区分这两者?很多文章只甩出了几个脏读、不可重复读、幻读的例子,却并没有解释清楚到底什么是什么 。
现在我可以肯定的说,脏读的条件不可重复读一定满足,但是如果是不可重复读,脏读却不一定满足,脏读属于不可重复读 。可以这么理解,RC级别下,相当于只解决了一部分不可重复读的问题 。
他是如何解决脏读的呢,锁机制:
1.事务A对当前被读取的数据加共享锁,一旦读完该行,立即释放该共享锁(注意是读完立即释放)
2.事务A在更新某行数据时,必须对其加上排他锁,直到事务结束才释放(注意是事务结束才释放)
 3、可重复读(REPEATABLE_READ)听起来,可重复读解决了不可重复读的问题 。事实是这样 。官方定义:


推荐阅读