更新后从另一个事务中可见,这是MySQL MVCC中的错误吗?
我的情况如下:更新后从另一个事务中可见,这是MySQL MVCC中的错误吗?,mysql,innodb,isolation-level,rocksdb,mvcc,Mysql,Innodb,Isolation Level,Rocksdb,Mvcc,我的情况如下: 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 UPDATE test SET value = value + 2 WHERE id =
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
UPDATE test SET value = value + 2 WHERE id = 1;
SELECT value FROM test WHERE id = 1;
12
COMMIT;
会话B
START TRANSACTION;
SELECT value FROM test WHERE id = 1;
10
SELECT value FROM test WHERE id = 1;
10
UPDATE test SET value = value + 3 WHERE id = 1;
SELECT value FROM test WHERE id = 1;
15
UPDATE test SET value = value + 3 WHERE id = 1;
会话A
START TRANSACTION;
SELECT value FROM test WHERE id = 1;
10
UPDATE test SET value = value + 2 WHERE id = 1;
SELECT value FROM test WHERE id = 1;
12
COMMIT;
会话B
START TRANSACTION;
SELECT value FROM test WHERE id = 1;
10
SELECT value FROM test WHERE id = 1;
10
UPDATE test SET value = value + 3 WHERE id = 1;
SELECT value FROM test WHERE id = 1;
15
UPDATE test SET value = value + 3 WHERE id = 1;
这里我得到了预期的结果,因为会话B有一个行id=1
的独立副本,即会话A的提交在这里不可见
但当我更新此行时,隔离会中断:
会话B
START TRANSACTION;
SELECT value FROM test WHERE id = 1;
10
SELECT value FROM test WHERE id = 1;
10
UPDATE test SET value = value + 3 WHERE id = 1;
SELECT value FROM test WHERE id = 1;
15
UPDATE test SET value = value + 3 WHERE id = 1;
根据这段关于MVCC的视频(15'00),此更新应该被拒绝。但是MySQL接受了这个更新
会话B
START TRANSACTION;
SELECT value FROM test WHERE id = 1;
10
SELECT value FROM test WHERE id = 1;
10
UPDATE test SET value = value + 3 WHERE id = 1;
SELECT value FROM test WHERE id = 1;
15
UPDATE test SET value = value + 3 WHERE id = 1;
因此,此选择得到了一个意外的结果:会话A的提交在会话B中可见
我的MySQL版本是5.7.26,隔离级别是可重复读取的
==更新===
本案例与MariaDB 10.4.10和RocksDB发动机的预期一样有效
在会话B中
START TRANSACTION;
SELECT value FROM test WHERE id = 1;
10
SELECT value FROM test WHERE id = 1;
10
UPDATE test SET value = value + 3 WHERE id = 1;
SELECT value FROM test WHERE id = 1;
15
UPDATE test SET value = value + 3 WHERE id = 1;
它回来了
ERROR 1213 (40001): Deadlock found when trying to get lock; try restarting transaction (snapshot conflict)
在InnoDB中,锁定语句不遵守可重复读取隔离 锁始终影响行的最新提交版本。因此,它们的行为就好像您使用了READ-COMMITTED 这会影响
更新
和删除
,以及锁定读取,如选择…进行更新
但一旦您更新了一行,新版本将在事务中可见。似乎
REPEATABLE-READ
不适用于这种“REPEATABLE-Write”场景。我将隔离级别更改为可序列化,并按预期工作:MVCC似乎未启用,行已锁定。