mysql - Mysql Gap-lock/Next-key 锁的规则
问题描述
我不确定为什么会发生以下行为。我认为它必须与间隙锁定/下一个键锁定有关。该文件提到了它们,但解释并不详细。
-- isolation level is Repeatable Read
-- create the table
create table t (id int primary key auto_increment, COL1 int, key idx_a(COL1));
insert into t (COL1) values(5), (10), (11), (13), (20);
select * from t;
---- ----
id | COL1
---- ----
1 | 5
2 | 10
3 | 11
4 | 13
5 | 20
-- in transaction 1
select * from t where COL1 = 13 for update;
-- in transaction 2
insert into t (COL1) values(10); -- success
insert into t (COL1) values(11); -- blocks
insert into t (COL1) values(12); -- blocks
.
.
insert into t (COL1) values(19); -- blocks
insert into t (COL1) values(20); -- success
-- in transaction 3
update t set COL1 = 11 where COL1 = 10; -- success
update t set COL1 = 12 where COL1 = 10; -- blocks
.
.
update t set COL1 = 20 where COL1 = 10; -- blocks
update t set a = 21 where a = 10; -- success
所以它看起来:
为 COL1 锁定 INSERT,其值为 [11, 20)(11 到 20,不包括 20)
UPDATE 锁定 COL1,值为 (11, 20] (11 到 20,排除 11)
我想知道为什么 MySQL 会这样?这种锁定的一般规则是什么?
解决方案
select * from t where COL1 = 13 for update;
此 sql 子句将锁定范围:
((11,3), (13,4)]
((13,4), (20,5)]
所以,我将在您的交易 2 和 3 中解释结果
insert into t (COL1) values(10); -- success because (10, 6) not in the gap range.
insert into t (COL1) values(11); -- block because (11, 7) in the gap range.
insert into t (COL1) values(12); -- block because (12, 8) in the gap range.
insert into t (COL1) values(19); -- block because (19, 9) in the gap range.
insert into t (COL1) values(20); -- success because (20, 10) not in the gap range.
update t set COL1 = 11 where COL1 = 10; --success because (11,2) not in the gap range.
update t set COL1 = 12 where COL1 = 10; -- blocks because (12,2) in the gap range.
update t set COL1 = 20 where COL1 = 10; -- blocks because (20,2) in the gap range.
update t set COL1 = 21 where COL1 = 10; -- success because (21,2) not in the gap range.
推荐阅读
- ibm-watson - 对话结束后如何发送最后一条消息
- html - “阅读更多”的 HTML/CSS 可折叠按钮不起作用
- javascript - 如何在不替换 ES6/Javascript 中的整个属性的情况下深度复制对象
- c - 结构与字符串文字?只读与读写?
- r - 在 sparklyr 中断开连接后会自动删除 spark 数据帧吗?如果没有,我们该怎么做?
- string - 字符串格式截断值
- c# - 将带空格的文件地址传递给 CMD
- javascript - 使用 JavaScript 在 HTML 中闪烁元素
- postgresql - 优化 PostgreSQL 的批量插入速度
- c# - 如何在 WPF 自定义控件中显示基本控件