Recipe
Transaction isolation levels explained
Understand dirty reads, non-repeatable reads, and phantom reads — and how each isolation level prevents them.
The four ANSI levels
| Level | Dirty read | Non-repeatable | Phantom |
|---|---|---|---|
| READ UNCOMMITTED | Possible | Possible | Possible |
| READ COMMITTED | Prevented | Possible | Possible |
| REPEATABLE READ | Prevented | Prevented | Possible |
| SERIALIZABLE | Prevented | Prevented | Prevented |
Quick glossary
- Dirty read
- Transaction A reads uncommitted changes from Transaction B. If B rolls back, A operated on data that never existed.
- Non-repeatable read
- Transaction A reads the same row twice and gets different values because Transaction B updated and committed in between.
- Phantom read
- Transaction A runs the same query twice and gets a different set of rows because Transaction B inserted or deleted matching rows.
Choosing a level
Start with READ COMMITTED — it is the default in PostgreSQL and prevents dirty reads without excessive locking. Move to REPEATABLE READ when your business logic requires a stable snapshot across multiple queries. Reserve SERIALIZABLE for financial ledgers or inventory systems where phantom writes would corrupt state.