我在学习mysql innodb engine next-key lock (under Repeatable Read level)时遇到一个问题。
这是我的表结构和表数据。
CREATE TABLE `o` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`a` int(10) DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `idx_a` (`a`)
) ENGINE=InnoDB AUTO_INCREMENT=9 DEFAULT CHARSET=utf8
+----+------+
| id | a |
+----+------+
| 1 | 1 |
| 3 | 1 |
| 5 | 3 |
| 7 | 6 |
| 10 | 8 |
+----+------+
我给字段a添加了一个普通的索引,然后插入了一些数据。 我开始第一笔交易(我们称之为 trx1)并运行以下命令:
mysql> begin;
Query OK, 0 rows affected (0.00 sec)
mysql> select * from o where a=3 for update;
+----+------+
| id | a |
+----+------+
| 5 | 3 |
+----+------+
1 row in set (0.00 sec)
我认为当我运行 select * from o where a=3 for update
时,mysql 将基于 next-key 机制锁定 (1,3],(3,6)。
接下来,我开始第二笔交易(我们称之为 trx2)并运行以下命令:
mysql> begin;
Query OK, 0 rows affected (0.00 sec)
mysql> select * from o where a=5 for update;
Empty set (0.12 sec)
让我吃惊的是,为什么 trx2 执行命令 select * from o where a=5 for update
成功。因为我认为 trx1 已经锁定 5 并且 trx2 将阻塞直到 trx1 提交。
如果有人能为我解答,我将不胜感激!!!
最佳答案
经过几天的学习,终于解决了。
trx1:select * from o where a=3 for update;
将使用间隙锁锁定 (1,6)。
trx2:select * from o where a=5 for update;
将使用间隙锁锁定 (3,6)。
间隙锁与间隙锁兼容!!!所以 trx2 不会阻塞。
关于RR下的mysql innodb engine next-key lock问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59138844/