I'm uncertain about how repeatable-read operates in RDBMS. I initially thought it functions similarly to Git branching, where an exact copy of the current database is utilized. However, I'm puzzled by the following scenario:
Tx1 Tx2
1. BEGIN; 1. BEGIN;
2. SELECT * FROM TABLE; (10 ROWS) 2. SELECT * FROM TABLE; (10 ROWS)
3. INSERT NEW ROW IN TABLE;
4. COMMIT;
3. UPDATE ROW WITH ID=11; (executes successfully)
When Tx1 and Tx2 are operating with independent snapshots, how can Tx2 access the newly created row by Tx1? I recognize this as an instance of phantom reads but am unclear about why it occurred.
You might mistaken phantom reads with non-repeatable reads and your example is specific to MySQL.
REPEATABLE READ
That phantom read you are getting is because you are inserting a new row, hence in doesn't modify any data that
Tx2
was reading in the first place. This case is documented (see link above) and allowing phantom reads!This is common for RDBMS to allow phantom reads on
REPEATABLE READ
isolation level. However different RDBMS defines it differently.This is handy reference that is possible and what not per isolation level:
This is what MySQL documentation is saying about phantom rows
As you can see it doesn't specify if gap is also from 103 to MAX_INT. Trying execute in a lock mode, you will see phantom rows.
This is why your
UPDATE
was successful.Interestingly enough if you run regular non locking
SELECT
after locking one, phantom rows will disappear.