数据库版本:MySQL5.7.33 Innodb RR隔离级别
CREATE TABLE `tests` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`number` int(11) unsigned NOT NULL DEFAULT '1',
PRIMARY KEY (`id`),
KEY `number` (`number`)
) ENGINE=InnoDB AUTO_INCREMENT=65 DEFAULT CHARSET=latin1;
数据
开始测试
- 第一步:事务1:select * from tests where number = 25 for update; 这里按照几乎所有的教程都说会锁住(20,30]的区间
- 第二步:事务2:insert into tests set number=20;会阻塞
- 第三步:事务3:insert into tests set number=30;不会阻塞
疑问
(20,30]不就是20 < x <= 30的意思吗?不是应该插入number=30阻塞,number=20不阻塞才对吗?为啥我测试正好反过来?
它其实是加的的是
间隙锁gap锁(左开右开)
,我理解是因为没有查询到记录,不是临建锁next-key(左开右闭)
,因为20也算是(20,30)范围内的数据所以会被阻塞,而30可能是(30,+无穷)的数据,可以简单做个实验,上面的内容是可以更新成功的,所以说明20这条记录并没有加锁,只是在30上加了间隙锁。