GAP锁为什么要锁住索引间的区间,而不是直接锁住值相等的就行了? 400 报错
如:
+-----+--------+---------+
| id | userId | name |
+-----+--------+---------+
| 100 | 100010 | ce1 |
| 200 | 100020 | 1232131 |
| 300 | 100030 | ce3 |
| 400 | 100040 | ce4 |
+-----+--------+---------+
id是PK, userId是普通非唯一索引
A事务:
begin;
update user set name ='tt' where userId='100030';
B事务:
insert into user (userId,name) values('100021','tttt');
因GAP锁插入阻塞
问题:为啥mysql是不直接阻塞插入100030的记录,而要阻塞间隙锁100020-100030, 100030-100040。
innodb在rr级别上的gap锁是为了解决幻读的问题
你说的相等值,其实就是rc级别的行级锁,只能避免不可重复读
######回复 @bboo : 嗯, 理解,确实是,谢了!######回复 @爱吃大肉包 : 我的意思是对于你这100030这数据的话,锁住一行就可以了.但是显然,只锁住一行是解决不了幻读的问题的,就如我刚才举的例子,删除一个不存在的索引举无法锁住一行.间隙锁是在性能和并发之间做一个取舍######回复 @bboo : 不知道我理解是否有问题,我理解的插入引起的幻读就是 update user set name ='tt' where userId='100030';影响行数就是1行,第二次2行。 如果改成select ...for update, 就是每次查出的记录都是一样的。 所以我才得出,只要锁住单条记录就行了。 你列举的 '8888888' 好像并没影响我的执行结果######回复 @bboo : 索引直接不存在,更不用谈加锁了,解决幻读只能通过间隙锁住 100040-正无穷 来控制8888888这个索引字段的插入. 而rc级别下就会通过行锁保证可重复读 innodb通过这些配置实际上隔离级别高了一个标准######回复 @爱吃大肉包 : 你考虑下删除的情况,比如你删除88888888的时候,这条数据不存在.版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。