mysql - RR下mysql innodb engine next-key lock问题
问题描述
我在学习mysql innodb engine next-key lock时遇到问题(在Reapeatable Read级别下)。
这是我的表结构和表数据。
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 不会阻塞。
推荐阅读
- .htaccess - htaccess 重定向奇怪的 url 目标。如何解决这个问题?
- java - Unirest POST 发送无法识别的字段(io.vertx.core.json.DecodeException 错误)
- javascript - 在表单输入中显示来自对象的正确数据
- ios - 在带有 A-Frame 的 iOS chrome 71 上无法播放视频
- rest - 查询字符串和路径参数的正确格式是什么?
- html - 更改按钮字体大小也会更改 ios 上的宽度
- c# - 您如何检测在聚焦任何窗口时按下的 XButton1?
- java - 仅显示最近添加的对象的数组列表
- r - 将栅格与可分割分辨率相关联
- python - 连接字典中的多个字符串并使用python保存在文件中