MySQL中的next-key lock

再次推荐一下丁奇的《MySQL实战45讲》,不同阶段阅读该专栏,总能收获不同的感悟。阅读本文,即默认已经知道“当前读”和“快照读”的含义了。

next-key lock是啥

间隙锁(Gap锁)和行锁合称 next-key lock。以该表t为例子:
在这里插入图片描述
在MySQL采用innodb,可重复读模式的情况下,执行如下语句:

select * from t for update

此时,for update情况下,select是基于当前读。那么会给该表加上间隙锁,锁住区间:(-⚮,0) (0,5) (5,10) (10,+supremum)

InnoDB 给每个索引加了一个不存在的最大值 supremum

除此之外,还会给该表加上一个行锁,锁住对应的行,综合间隙锁来看,我们可以采用一个左开右闭的区间表示。

(-,0] (0,5] (5,10] (10,+supremum]

行锁 +间隙锁 组成了我们的 next-key lock

有啥用

有人说innodb,可重复读的情况下,还会出现幻读的现象。其实这里涉及到对幻读的一个理解。

  • 可重复读隔离级别下,普通的查询属于快照读,是不会看到别的事务插入的数据的。因此,幻读只有可能在“当前读”下才会出现。
  • 但此种情况亦不能称为幻读。
  • 幻读仅专指“新插入的行”。

也就是说,通过next-key lock, 在innodb,可重复读的情况下,幻读的现象是已经解决的。(感谢间隙锁~)

幻读如何产生

只考虑行锁,不考虑间隙锁,以上图作为待查寻的表,查询结果如图:

  1. sessionA开启一个事务,在第一次查询的情况下结果是(5,5,5)
  2. 但sessionA在第二次查询的时候,缺查出来了3条记录。
  • 首先,针对SessionB的更新操作,由于SessionA的读采用的是当前读,所以结果无可厚非,但这种情况不能算作幻读。(第二部分已经澄清何为幻读)
  • 那么,针对SessionC的新插入记录在SessionA下,被读取到了,此种情况发生了幻读。

在这里插入图片描述
考虑间隙锁后,在SeesionA执行如下语句的时候,不仅给记录加上了3个行锁,还加上了4个间隙锁,保证在SessionA提交事务前,不会有新纪录插入进来。

select * from t where b=5 for update

猜你喜欢

转载自blog.csdn.net/legendaryhaha/article/details/114286239