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加锁有下面几个规则。
-
Next-Key Lock是前开后闭区间。
-
查找过程中访问到的对象才会加锁。
-
索引上的等值查询,给唯一索引加锁的时候,next-key lock退化为record lock。
-
索引上的等值查询,向右遍历时且最后一个值不满足等值条件时,next-key lock退化为gap lock。
分析上图的两个事务的操作,在A事务加锁之后,实际的加锁范围是[10,30),sql查询流程如下:
-
通过score索引,找到第一个值,score=10,不满足条件,继续向下寻找。
-
找下一个节点score=20,符合条件,会加上行锁和间隙锁。此时的加锁状态是(10,20];但是根据规则2,查找过程访问到的上一个记录score=10,所以会将10也锁住,加锁范围变成[10,20]。
-
score不是唯一索引,所以会继续向下寻找,下一个节点为30,满足规则2,所以会加上(20,30],但是30不满足等值查询score=20,所以根据第4条规则next-key lock退化为gap lock(20,30)。
-
至此,事务加锁结束,最终的加锁范围是[10,30)
本文摘自: