2016-07-29 58 views
2

enter image description here这个innodb差距锁定错误?

TRX1 SELECT * FROM表,其中REFID = 4更新

TRX2 插入到表(REFID)值(2);块

trx2将被封锁,我知道trx1将保持它的差距锁定,[1,4),[4,7);

我的问题是为什么保持差距锁定? “insert val 2”不冲突“select refId = 4 for update”,为什么innodb会保持间隙锁定,为什么不使用记录锁定?

这个问题一直困扰着我很长一段时间,请科技上帝救我。

回答

1

有趣的问题。

需要使用间隙锁来避免phantom rows。 默认情况下,MySQL工作在REPEATABLE-READ隔离级别。如果您在交易中多次运行select ... for update,则应始终返回相同的结果。 假设您没有间隙锁定,并且trx2插入了refId = 4的另一行(索引不唯一)。 然后按照TRX1选择将返回两行:

MariaDB [test]> select * from t1 where refId=4 for update; 
+----+------+ 
| id | refId| 
+----+------+ 
| 2 | 4 | 
| 4 | 4 | 
+----+------+ 
2 rows in set (0.00 sec) 

这是不一样的结果作为第一选择。

+0

yes,没错,虚幻行,跟随你的测试,插入refId = 4的另一行,只要trx1保持行记录锁定(或没有间隙锁定),你可以阻塞插入refId = 4,并且虚幻幻影行;我的问题为什么保持差距锁定插入refId = 1,2,3,5,6,不仅仅是4.感觉这是mysql的bug? –

+0

我认为这个sql的gap-lock工作“select * from refId <10 for update”,gap-lock将阻止插入refId = 1,2,3,4,5,6,7到void虚线行;它应该工作范围搜索条件,而不是等于条件。 –

+0

感谢您的回答。 –