Critical Anomalies: Dirty Reads, Non-Repeatable Reads, and Phantoms
Why Anomalies Matter
Isolation levels exist to prevent specific failure modes called anomalies. When concurrent transactions interact without proper isolation, they can produce incorrect results even though each transaction individually follows the rules. Understanding these anomalies helps you choose the right isolation level for your workload.
Dirty Read
A transaction reads data written by another transaction that has not yet committed. If that transaction rolls back, the reader used values that never actually existed. Example: Transaction A reads inventory count of 50 from uncommitted Transaction B, allocates those units, then B rolls back revealing count was 10. A oversold by 40 units. Prevented at Read Committed and above.
Non-Repeatable Read
A transaction reads the same row twice and gets different values because another transaction modified and committed between reads. Example: Banking transaction reads balance as $1,000, validates withdrawal, another transaction debits $600, then A re-reads seeing $400. Validation used stale data. Prevented at Repeatable Read and above.
Phantom Read
A transaction executes a query twice and gets different sets of rows because another transaction inserted or deleted matching rows. Unlike non-repeatable reads (existing rows change), phantoms involve rows appearing or disappearing. Example: A checks for overlapping reservations, finds none, inserts. Meanwhile B does the same. Both pass validation but create double-booking. Only Serializable fully prevents phantoms, though some databases use gap locking (locking range between existing records) at Repeatable Read.
The Severity Hierarchy
Dirty reads are most dangerous (reading uncommitted garbage). Non-repeatable reads are less severe (data was at least committed). Phantoms are subtlest (query results change due to new rows). Higher isolation levels prevent more anomalies but cost more in performance or concurrency.