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

LevelDirty readNon-repeatablePhantom
READ UNCOMMITTEDPossiblePossiblePossible
READ COMMITTEDPreventedPossiblePossible
REPEATABLE READPreventedPreventedPossible
SERIALIZABLEPreventedPreventedPrevented

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.