MySQL 的 RR 隔离级别通过 MVCC + Next-key Locks 解决幻读问题
幻读
在一次事务中,多次查询之后,结果集的个数不一致的情况叫做幻读。而多出来或者少的哪一行被叫做幻行
在高并发数据库系统中,需要保证事务与事务之间的隔离性,还有事务本身的一致性
解决方法
在快照读读情况下, MySQL 通过 MVCC 来避免幻读。
在当前读读情况下, MySQL 通过 next-key lock 来避免幻读。
1
2
select * from t where a=1; # 属于快照读
select * from t where a=1 lock in share mode; # 属于当前读
不能把 快照读 和 当前读 得到的结果不一样这种情况认为是幻读,这是两种不同的使用。所以可认为 MySQL 的 RR 级别是解决了幻读的。
多版本并发控制(MVCC)(快照读/一致性读)
多数数据库都实现了多版本并发控制,并且都是靠保存数据快照来实现的。
事务每次取数据的时候都会取创建版本小于当前事务版本的数据,以及过期版本大于当前版本的数据。
普通的 select 就是快照读。
1
select * from T where number = 1;
原理:将历史数据存一份快照,所以其他事务增加与删除数据,对于当前事务来说是不可见的。
next-key lock(当前读)
next-key lock 包含两部分:
- 记录锁(行锁)
- 间隙锁 记录锁是加在索引上的锁,间隙锁是加在索引之间的。