原文:MySQL事务隔离级别和MVCC https://juejin.im/post/6844903808376504327#heading-6
MVCC文章勘误:https://juejin.im/post/6844903815863336973
自己整理的:
脏读:在一个事务处理过程里读取了另一个未提交的事务中的数据。
不可重复读:一个事务读取到了其他事务已经提交的数据,导致前后两次读取数据不一致的情况,称为不可重复读。
幻读:一个事务前后两次读取数据不一致,是由于其他数据插入数据造成的,这种情况叫做幻读。
所谓的MVCC(Multi-Version Concurrency Control ,多版本并发控制)指的就是在使用
READ COMMITTD
、REPEATABLE READ
这两种隔离级别的事务在执行普通的SEELCT
操作时访问记录的版本链的过程,这样子可以使不同事务的读-写
、写-读
操作并发执行,从而提升系统性能。READ COMMITTD
、REPEATABLE READ
这两个隔离级别的一个很大不同就是生成ReadView
的时机不同,READ COMMITTD
在每一次进行普通SELECT
操作前都会生成一个ReadView
,而REPEATABLE READ
只在第一次进行普通SELECT
操作前生成一个ReadView
,之后的查询操作都重复这个ReadView
就好了。RR 和 RC 的区别:
- RR 可避免 不可重复读,RC 可能 出现 不可重复读的情况
- RR 隔离级别下,普通的select使用快照读(snapshor read),底层使用MVCC来实现;
加锁的select(select..... in share mode/ select ... for update) 以及更新操作 update,delete等语句使用当前读(current read),底层使用记录锁、或者间隙锁、临键锁。 - RC 隔离级别下,普通的select使用快照读,使用MVCC来实现;
加锁的select都是用记录锁,因为没有间隙锁(Gap Lock)。除了两种特殊情况--外键约束检查以及重复键检查时会使用间隙锁封锁区间。
mysql如何实现避免幻读
- 在快照读情况下,mysql通过mvcc来避免幻读。
- 在当前读情况下,mysql通过next-key来避免幻读
什么是快照读和当前读
-
快照读:简单的select操作,属于快照读,不加锁。
- select * from table where 。。。;
-
当前读:特殊的读操作,插入/更新/删除操作,属于当前读,需要加锁。
- select * from table where ? lock in share mode;
- select * from table where ? for update;
- insert into table values (…);
- update table set ? where ?;
- delete from table where ?;