TRX1
select * from table from refId = 4进行更新
TRX2
插入表(refId)值(2);块
trx2将被阻止,我知道trx1会保持间隙锁定,[1,4],[4,7];
我的问题是为什么要保持差距? “插入val 2”不冲突“选择refId = 4 for update”,为什么innodb会保持间隙锁定,为什么不使用记录锁?
这个问题困扰了我好久,请科技上帝拯救我.
解决方法:
有趣的问题.
需要间隙锁定以避免phantom rows.
MySQL默认工作在REPEATABLE-READ隔离级别.如果你多次运行select for for update in the transaction,它应该总是返回相同的结果.
假设您没有间隙锁定,并且trx2插入了另一行,其中refId = 4(索引不是唯一的).
然后在trx1中的select后面将返回两行:
MariaDB [test]> select * from t1 where refId=4 for update;
+----+------+
| id | refId|
+----+------+
| 2 | 4 |
| 4 | 4 |
+----+------+
2 rows in set (0.00 sec)
它与第一次选择的结果不同.