Here is my case:
CREATE TABLE test (id INT NOT NULL PRIMARY KEY AUTO_INCREMENT, value INT DEFAULT 0);
INSERT INTO test (id, value) VALUES (1, 10);
Session A
START TRANSACTION;
SELECT value FROM test WHERE id = 1;
10
Session B
START TRANSACTION;
SELECT value FROM test WHERE id = 1;
10
Session A
UPDATE test SET value = value + 2 WHERE id = 1;
SELECT value FROM test WHERE id = 1;
12
COMMIT;
Session B
SELECT value FROM test WHERE id = 1;
10
Here I get the expected result because Session B have an isolated copy of row id = 1
, i.e. the commit from Session A is NOT visible here.
But when I update this row, the isolation breaks:
Session B
UPDATE test SET value = value + 3 WHERE id = 1;
According to this video https://www.youtube.com/watch?v=sxabCqWsFHg about MVCC (at 15'00), this update should be rejected. But MySQL accepted this update.
Session B
SELECT value FROM test WHERE id = 1;
15
So this select gets an unexpected result: the commit from Session A is visible in Session B.
My MySQL version is 5.7.26, and the isolation level is REPEATABLE-READ.
=== UPDATE ===
This case works as expected for MariaDB 10.4.10 with RocksDB engine.
In Session B
UPDATE test SET value = value + 3 WHERE id = 1;
It returns
ERROR 1213 (40001): Deadlock found when trying to get lock; try restarting transaction (snapshot conflict)
In InnoDB, locking statements don't obey the REPEATABLE-READ isolation.
Locks always affect the most recently committed version of the row. So they behave as if you had used READ-COMMITTED.
This affects
UPDATE
andDELETE
, as well as locking reads such asSELECT...FOR UPDATE
.But once you do UPDATE a row, the new version becomes visible in your transaction.