【发布时间】:2020-04-13 21:47:21
【问题描述】:
这是我的情况:
CREATE TABLE test (id INT NOT NULL PRIMARY KEY AUTO_INCREMENT, value INT DEFAULT 0);
INSERT INTO test (id, value) VALUES (1, 10);
会话 A
START TRANSACTION;
SELECT value FROM test WHERE id = 1;
10
会话 B
START TRANSACTION;
SELECT value FROM test WHERE id = 1;
10
会话 A
UPDATE test SET value = value + 2 WHERE id = 1;
SELECT value FROM test WHERE id = 1;
12
COMMIT;
会话 B
SELECT value FROM test WHERE id = 1;
10
在这里我得到了预期的结果,因为 Session B 有行 id = 1 的独立副本,即来自 Session A 的提交是 NOT 在这里可见。
但是当我更新这一行时,隔离就会中断:
会话 B
UPDATE test SET value = value + 3 WHERE id = 1;
根据此视频https://www.youtube.com/watch?v=sxabCqWsFHg 关于 MVCC(15'00),此更新应被拒绝。但是 MySQL 接受了这个更新。
会话 B
SELECT value FROM test WHERE id = 1;
15
所以这个选择得到了一个意想不到的结果:来自 Session A 的提交在 Session B 中是可见的。
我的MySQL版本是5.7.26,隔离级别是REPEATABLE-READ。
=== 更新 ===
此案例在带有 RocksDB 引擎的 MariaDB 10.4.10 中按预期工作。
在会话 B
UPDATE test SET value = value + 3 WHERE id = 1;
返回
ERROR 1213 (40001): Deadlock found when trying to get lock; try restarting transaction (snapshot conflict)
【问题讨论】:
标签: mysql innodb isolation-level rocksdb mvcc