更新后从另一个事务中可见,这是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似乎未启用,行已锁定。