MySQL学习笔记4

189 阅读2分钟

GAP LOCK(间隙锁)

InnoDB为了解决幻读,就引入了间隙锁(Gap Lock),间隙锁锁的是两个值之间的空隙。

间隙锁的范围是开区间,不包含两个端点.

间隙锁加行锁合起来就是next-key lock,next-key lock是前开后闭区间。

GAP Lock只会出现在RR隔离级别下。

GAP LOCK理解实例(普通索引下的gap lock,非唯一索引):

从上图可以发现,插入score为10、15、25都插入失败,score为30的时候插入成功。原因是SessionA的select操作,不止锁了score为20的行。

从数据库的记录和索引字段,我们可以分析,这个表的间隙被分成了下面的情况:

  • (negative infinity,10)

  • (10,20),

  • (20,30),

  • (30,40)

  • (40,positive infinity)

而RR隔离级别,默认是使用Next-key Lock,Next-Key Lock加锁有下面几个规则。

  1. Next-Key Lock是前开后闭区间。

  2. 查找过程中访问到的对象才会加锁。

  3. 索引上的等值查询,给唯一索引加锁的时候,next-key lock退化为record lock。

  4. 索引上的等值查询,向右遍历时且最后一个值不满足等值条件时,next-key lock退化为gap lock。

分析上图的两个事务的操作,在A事务加锁之后,实际的加锁范围是[10,30),sql查询流程如下:

  1. 通过score索引,找到第一个值,score=10,不满足条件,继续向下寻找。

  2. 找下一个节点score=20,符合条件,会加上行锁和间隙锁。此时的加锁状态是(10,20];但是根据规则2,查找过程访问到的上一个记录score=10,所以会将10也锁住,加锁范围变成[10,20]。

  3. score不是唯一索引,所以会继续向下寻找,下一个节点为30,满足规则2,所以会加上(20,30],但是30不满足等值查询score=20,所以根据第4条规则next-key lock退化为gap lock(20,30)。

  4. 至此,事务加锁结束,最终的加锁范围是[10,30)

本文摘自

www.modb.pro/db/180054