加锁规则
- [原则1]加锁基本单位是next-key lock,(前开后闭]
- [原则2]查询访问到的对象才加锁
- [优化1]索引上的等值查询,给唯一索引加锁,next-key lock退化为行锁
- [优化2]索引上的等值查询,向右遍历时且最有一个值不满足等值条件时,next-key lock退化为间隙锁。
- [bug]唯一索引上的范围查询会访问到不满足条件的第一个值为止
CREATE TABLE `t` (
`id` int(11) NOT NULL,
`c` int(11) DEFAULT NULL,
`d` 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,加锁单位时next-key lock,sessionA加锁范围(5,10]
- 优化2,这是一个等值查询(id=7),而id=10不满足条件,next-key lock退化为间隙锁.因此最终加锁范围时(5,10)
所以 sessionB插入8被锁住,而sessionC修改10这行是可以的。
案例二:非唯一索引等值锁

- 原则1,加锁单位时next-key lock,因此会给(0,5]加上next-key lock
- c是普通索引,因此仅访问c=5不能马上停下来,需要向右遍历,查到c=10才放弃。原则2,访问到的都要加锁,因此给(5,10]加next-key lock
- 优化2,索引等值判断,向右遍历,最后一个不满足c=5。next-key lock退化为间隙锁(5,10)
- 原则2,只有访问到才加锁。该查询使用覆盖索引,不需要访问主键索引,所以主键索引没有加任何锁,所以sessionB的update语句可以执行完成。
但sessionC要插入一个(7,7,7)但记录,就被sessionA的间隙锁锁住。
锁-修改
原文:https://www.cnblogs.com/KelvinFan/p/12953630.html