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

 
 
上一篇MySQL的文章讲了事务的特性和原理(
最详细的MySQL事务特性及原理讲解!(一)
) 作为基础,小伙伴们自行查看 。
关于MySQL隔离级别的讲解,网上已经很多了 。和大家一样,我也看过很多很多,但是发现看完之后还是晕晕乎乎,学习走了很多弯路 。事务特性的原理是什么?什么隔离级别可以解决什么问题?具体什么原理?这些似乎都没有讲清楚,无非是抄来抄取,甚至都抄错了,我查了近10篇文章每篇都有各种各样的错误!比如下面这个举例:

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

文章插图
 
作者说RR解决了幻读的问题,并且还不止一个人这样说 。还有说未提交读级别下不加锁 。
二 最详细MySQL事务隔离级别及原理讲解!

文章插图
 
那么事实是这样吗?(阅读提醒:点收藏前先点「在看」,记忆效果翻倍!)
隔离性与原子性、持久性侧重于研究事务本身不同,隔离性研究的是不同事务之间的相互影响 。隔离性是指,事务内部的操作与其他事务是隔离的,并发执行的各个事务之间不能互相干扰 。
严格的隔离性,对应了事务隔离级别中的Serializable (可串行化),但实际应用中出于性能方面的考虑很少会使用可串行化 。隔离性追求的是并发情形下事务之间互不干扰 。SQL标准定义了4类隔离级别:Read Uncommitted(读取未提交内容)、Read Committed(读取提交内容)、Repeatable Read(可重读)、Serializable(可串行化) 。
对于隔离性的探讨,主要可以分为两个方面:
1.锁机制保证隔离性
2.MVCC保证隔离性 。
隔离级别原理及问题严格的隔离性,对应了事务隔离级别中的Serializable (可串行化),但实际应用中出于性能方面的考虑很少会使用可串行化 。所以,共有四种隔离级别来对应不同的业务性能需求 。然而正是由于不同的隔离级别,便产生了不同的问题 。
我们不妨带着几个问题去继续阅读:
1.可重复读和幻读的区别是什么?
2.每个隔离级别解决了怎样的问题?怎么解决的?
1、读未提交(READ_UNCOMMITTED)顾名思义,该隔离级别下可以读取到另一个事务未提交的数据 。严谨一点,我们给出官方定义:
The isolation level that provides the least amount of protection between transactions. Queries employ a locking strategy that allows them to proceed in situations where they would normally wait for another transaction. However, this extra performance comes at the cost of less reliable results, including data that has been changed by other transactions and not committed yet (known as dirty read). Use this isolation level with great caution, and be aware that the results might not be consistent or reproducible, depending on what other transactions are doing at the same time. Typically, transactions with this isolation level only do queries, not insert, update, or delete operations.
如文档所说,它提供了最低的隔离级别,查询时采用无需等待其他事务的锁策略 。所以,在这个隔离级别下,基本上什么问题都会产生了 。于是文档建议,通常具有此隔离级别的事务仅执行查询,而不执行插入,更新或删除操作 。
但是,这并不代表他一无是处 。其实RU隔离级别解决了一个问题——当A事务修改数据n,B事务也修改数据n,后执行的语句会把另一个事务的结果覆盖 。如文章开头提到的反例,如果读未提交隔离级别下不加锁,这是不可能实现的 。
为了解决丢失修改的写覆盖问题,未提交读规定:
1.事务A对当前被读取的数据不加锁,事务B读取也不加锁 。
2.事务A开始更新一行数据时,必须先对其加排他锁,直到事务结束才释放 。
如何证明呢?
事务A事务B
二 最详细MySQL事务隔离级别及原理讲解!

文章插图
 

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

文章插图
 

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

文章插图
 

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

文章插图
 

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

文章插图
 
发生脏读 和 等待
二 最详细MySQL事务隔离级别及原理讲解!

文章插图
 
图中左边为事务A,右边为事务B,可见事务A更新时加排他锁,事务未提交,所以事务B更新数据发生阻塞 。但是B却可以读取到A修改后的数据,说明B在读取时并未加任何锁 。


推荐阅读