SQL Transaction Isolation Levels

READ UNCOMMITTED through SERIALIZABLE with anomaly prevention and lock behavior.

Reference for the four ANSI SQL transaction isolation levels with the read anomalies each prevents (dirty, non-repeatable, phantom) and the default level per major database.

What are the four ANSI SQL isolation levels?

From weakest to strongest: Read Uncommitted, Read Committed, Repeatable Read and Serializable. Each higher level prevents more concurrency anomalies at the cost of more locking or aborts, so stronger isolation trades throughput for correctness.

Choosing an isolation level

A transaction’s isolation level controls how much it is shielded from concurrent transactions. The ANSI SQL standard defines four levels — Read Uncommitted, Read Committed, Repeatable Read and Serializable — each ruling out more read anomalies as you go stronger, in exchange for more locking, blocking or aborts. This reference shows which anomalies each level allows and the default level chosen by the major databases.

How it works

The standard is defined by three anomalies a level may permit:

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

* Several engines (PostgreSQL snapshot, MySQL InnoDB next-key locks) also block phantoms at Repeatable Read, exceeding the bare ANSI requirement. Set it per session or per transaction:

SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;
BEGIN; -- ... ; COMMIT;

Tips and notes

  • Stronger isolation costs concurrency: Serializable may abort transactions you must retry, so design for retry loops at that level.
  • “Repeatable Read prevents phantoms” depends on the engine — true in InnoDB and PostgreSQL snapshots, not guaranteed by ANSI alone.
  • Read Committed is the pragmatic default for most OLTP workloads.
  • Read Uncommitted is rarely useful and is effectively unavailable in PostgreSQL (it behaves as Read Committed).
  • For correctness-critical invariants spanning multiple rows, prefer Serializable or explicit row locks over hand-rolled checks at weaker levels.