2021-04-02 Next-Key Lock 解决幻读

上文中已经总结了Mysql是如何利用MVCC实现四个隔离级别的,但是对于幻读问题,MVCC是无能为力的。在RR隔离级别下是使用Next-Key Lock 来解决幻读的.

Next-Key Lock

行锁 : 锁定的是当前行的索引,如果没有索引会默认锁定隐式索引
间隙锁 : 锁定的是一个不存在的间隙
Next-Key Lock : 行锁+间隙锁的实现,也是解决幻读问题的关键

原理

//事务A                                        事务B
BEGIN;                                         BEGIN;
SELECT COUNT(*) FROM ttt;                    
                                               INSERT INTO ttt values(2,'aaaa');
SELECT COUNT(*) FROM ttt;

显而易见,在这样的情况下,事务A的两次查询结果必然不一致。那么如何解决这个问题,实际上很简单。我们只需要保证一个事务查询的区间在查询过程中不能够被操作即可。

通俗来讲,就是为事务A实现一个范围锁,这个范围就是该区间。

例如执行SELECT * FROM table WHERE id BETWEEN 1 AND 200,那么我们只需要保证在这个区间查找时,别的事务不能够对该区间进行增添删除操作即可,这里就利用到了我们上面所提到的间隙锁。

间隙锁的本质是锁住一个目前并不存在的数据,假设我们在id[100,200]这个区间中只有一个id=150的数据,但是对这个区间添加间隙锁,就能够将id=[100,150)(150,200]的空间全部锁住,也就是说,这时候只能够操作id=150的行,而其他行已经被锁住。

全表加锁的情况

//事务A                                        事务B
BEGIN;                                         BEGIN;
SELECT COUNT(*) FROM ttt;                    
                                               INSERT INTO ttt values(2,'aaaa');
SELECT COUNT(*) FROM ttt;
开启事务A,执行第一次查询,由于没有where条件所以全表加Next-Key Lock

事务B,插入数据并提交,由于事务A全表加Next-Key Lock,所以在事务A中不会显示有新增数据

事务A果然没有新增数据

部分数据加锁

//事务A                                        事务B
BEGIN;                                         BEGIN;
select * from ttt WHERE id BETWEEN 1 AND 200;                    
                                               INSERT INTO ttt values(250,'aaaa');
select * from ttt ;
事务A,只锁定1~200行的数据,200行之后不做锁定,所以插入250行数据可以显示

事务B,插入250行数据

事务A,可以查到两条数据

可以看到当事务A使用COUNT(*)操作时,会锁止整个表,因为这个语句涉及的区间是整个空间,而如果是类似于BETWEEN ... AND ...这类语句,则只会锁住表内一段空间,如果去操作其他的空间,就不会发生阻塞.

总结

从上边的描述中我们可以看出来,所谓的MVCC(Multi-Version Concurrency Control ,多版本并发控制)指的就是在使用READ COMMITTD、REPEATABLE READ这两种隔离级别的事务在执行普通的SEELCT操作时访问记录的版本链的过程,这样子可以使不同事务的读-写、写-读操作并发执行,从而提升系统性能。READ COMMITTD、REPEATABLE READ这两个隔离级别的一个很大不同就是生成ReadView的时机不同,READ COMMITTD在每一次进行普通SELECT操作前都会生成一个ReadView,而REPEATABLE READ只在第一次进行普通SELECT操作前生成一个ReadView,之后的查询操作都重复这个ReadView就好了。

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容