Notes
This paper discusses ANSI’s isolation levels and the phenomena that each one allows, and then discusses new phenomena that can happen. These have been extended throughout the years as well.
ANSI’s four Phenomena
- Dirty Write: A transaction overwrites another transaction’s uncommitted update.
- initially, = 0.
- writes to 10. It doesn’t commit or abort yet.
- writes to 20. It then commits.
- then aborts.
- This breaks later undo of to .
- Dirty Read: A transaction reads data from another uncommitted transaction.
- initially, = 0, = 0.
- writes to 10.
- reads , which is 10. It has code to set to 10 if is 10.
- then aborts.
- then sets to 10, and aborts.
- is set to 10 even though was never 10 in a committed transaction.
- Nonrepeatable Read: A transaction reads a row, another transaction changes it before the first commits.
- initially, = 100.
- reads , which is 100.
- writes to 150, and then commits.
- then reads again later in the transaction, and sees 150. It commits.
- Thus, cannot repeat its read.
- Phantom Read: A transaction reads a set of rows, transaction 2 updates rows match that predicate.
- initially, is the number of doctors, 1.
- There is a constraint, that there must always be 1 doctor available per shift.
- makes sure that there’s at least one doctor twice, once at the beginning and once at the end of the transaction, before reporting the shift is ok.
- notes that a doctor has to take vacation. So is set to 0.
- reads again, and notes that is 0, so a row disappeared.
New Phenomena
-
Lost Update:
- reads at .
- reads at and then increments it. It then commits, incrementing to .
- still has its copy of from , so it also increments it as well. This overwrites ‘s update, and only one increment is persisted, even though and complete.
- This can happen under Read Committed, and is prevented by Repeatable Read.
-
Cursor Lost update:
- Pretty much the same as Lost Update, just using a cursor. This is fixed by Cursor Stability, where on FETCH of a cursor, the row it fetched is locked for reads, making updating that row impossible and removing lost update for cursors.
-
Read Skew:
- The table has a constraint, , which is a property of columns and .
- reads .
- updates and , following , and commits.
- then reads .
- Since sees at and at , is no guarantee that is enforced.
-
Write Skew:
- The table has a constraint, , which is a property of columns and .
- reads and .
- reads and .
- writes and commits, maintaining .
- writes and commits, maintaining .
- There is no guarantee that holds, since and were written at different times.
Other Phenomena
There are more phenomena as well — Adya has Generalized Isolation Level Definitions (GILD). which discuss the following:
- Write Cycles:
- Initially, = 0.
- reads and increments it to 1. It then commits.
- reads and increments it twice in the transaction. It then commits.
- should be 3, but it is 2, so has overwritten .
- Aborted reads:
- Initially, = 0.
- sets = 1, and then = 2, and then aborts.
- reads in the middle of , reading 1, an aborted read.
- Intermediate read:
- Initially, = 0.
- sets to 10 at , and then x to 20 at in a long running transaction, then commits at .
- reads at , so it sees = 10. However, this value of has never been committed.
- Cyclic Information Flow:
- Initially, = 0, and = 0.
- sets = 1.
- sets = 1.
- Then, reads , which is 1.
- Then, reads , which is 1.
- This means that , which makes this impossible to serialize.
- Anti-dependency cycles:
- Initially, = 0, and = 0.
- is that at most, or can be 1.
- reads and , and sees they are both 0. It then sets to 1, which satisfies , because it believes is 0. It commits.
- reads and , and sees they are both 0. It then sets to 1, which satisfies , because it believes is 0. It commits.
- = 1 and = 1, which violates , even though both transactions followed in their transaction.