一、行锁加锁规则
在RR隔离级别,行锁的加锁规则:
1、加锁原则:加锁的基本单元是next-key lock(前开后闭区间),且查找过程中访问的对象才会加锁
2、等值查询next-key lock退化情况:
(1)唯一索引上的等值查询,查询到结果时,next-key lock退化成行锁
(2)索引上的等值查询,向右遍历到最后一个不满足等值条件的值时,next-key lock退化成间隙锁。
对于退化情况2:举个例子来看:
CREATE TABLE t(id int(11) NOT NULL, d int(11) DEFAULT NULL, c int(11) DEFAULT NULL, PRIMARY KEY (id), KEY c(c))ENGINE=InnoDB;
INSERT INTO t VALUES(0, 0, 0),(5, 5, 5),(10,10,10),(15,15,15),(20,20,20),(25,25,25);
现在在事务1中执行:
BEGIN;
SELECT id FROM t WHERE c=5 lock in share mode;
此时加锁区间分析:
首先查询方式是索引查询,因此在索引树中搜索的区间(0,5]会加next-key lock((0,5)的间隙锁和id为5的行锁)
其次因为不是唯一索引且没有做limit限制,此时会向右遍历到最后一个不满足c=5的值,即加上next-key lock (5,10] 根据退化规则,此时next-key lock (5,10]退化成(5,10)
另外需要注意的是,只有访问的对象才加锁,由于当前查询是覆盖索引,所以主键索引上是没有任何加锁。此时其他事务执行update t set d=d+1 where id=5;是不会阻塞的。但是如果是for update的情况下,系统会
默认你需要更新主键,因此也会给主键上加上行锁
3、范围查询需要注意两个唯一索引的点:
(1)对于范围查询,唯一索引范围查询可能退化成行锁(范围查询时可能使用等值查询然后再进行范围查询,此时唯一索引的等值查询可能会退化成行锁)。
(2)唯一索引的范围查询会访问到不满足条件的第一个值为止。