这是我的情况:
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有一个独立的 row 副本id = 1
,即来自Session A的提交在这里不可见。
但是当我更新这一行时,隔离中断:
会议 B
UPDATE test SET value = value + 3 WHERE id = 1;
根据这个关于 MVCC 的视频https://www.youtube.com/watch?v=sxabCqWsFHg(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)