read-committed-isolation · also Read Committed, READ COMMITTED

Read Committed isolation

Read Committed is a transaction isolation level that excludes dirty reads but can allow later statements to observe changes committed by other transactions.

Related Observatory article: Read Committed isolation on hesela.com

The level does not require a particular concurrency-control mechanism. Berenson et al. distinguish phenomenon-based definitions from locking implementations; a shared label is not evidence of identical behavior. Nonrepeatable reads and phantoms remain possible. [1]

In PostgreSQL 18, an ordinary SELECT uses a statement-start snapshot and sees its own transaction's previous writes. Successive statements can therefore see different committed states. Updating commands have additional concurrent-row recheck behavior; do not generalize the ordinary-read rule to every command. [2]

Isolation and persistence answer different questions. Choosing this level does not specify a failure model, backup policy or durable acknowledgement boundary. See the companion analysis for a constructed two-read history. [3]

PostgreSQL ON CONFLICT DO NOTHING can reject a proposed insertion because of a row outside the statement snapshot. A fallback SELECT in the same data-modifying WITH statement need not find that row; a later command obtains a new Read Committed snapshot. [4] [5]

Hesela's ten controlled PostgreSQL 16.15 cases, each captured twice on one host/build, include an empty get-or-create result after a competing commit. An unchanged-value DO UPDATE returned the identity but fired row and statement UPDATE triggers; WHERE false returned no identity but still fired the statement trigger. A deletion before the next lookup made it empty again. This is neither a new database defect nor an unconditional retry guarantee. Native observations, code and raw captures are available in the reproduction packet. [6] [7] [8]

Relations

related
Snapshot isolation, Read-atomic isolation, Serializability, Fractured read

Limitations

  • A conditional conflict UPDATE still locks the conflicting row even when its predicate prevents a row update; it is not a lock-free lookup. This is a documented boundary, not a lock-duration measurement. [6]

Citations

  1. Berenson et al. A Critique of ANSI SQL Isolation Levels. SIGMOD 1995; MSR-TR-95-51, sections 2.2-2.3, Tables 1-2. (accessed 2026-11-13)
  2. PostgreSQL 18 documentation: Transaction Isolation, section 13.2.1. (accessed 2026-11-13)
  3. Hesela: Storage consistency, ordering, transactions and durability. (accessed 2026-11-13)
  4. PostgreSQL 16: Transaction Isolation, sections 13.2.1-13.2.2; conflict visibility and transaction restart. (accessed 2026-11-13)
  5. PostgreSQL 16: WITH Queries, section 7.8.4; shared snapshots and RETURNING. (accessed 2026-11-13)
  6. PostgreSQL 16: INSERT; RETURNING and rows locked but not updated. (accessed 2026-11-13)
  7. PostgreSQL 16: Overview of Trigger Behavior, section 39.1; statement-level conflict UPDATE triggers. (accessed 2026-11-13)
  8. Hesela: PostgreSQL 16.15 conflict-visibility observations, executable protocol and raw evidence. (accessed 2026-11-13)
Sources & caveats
  • Original level definition and PostgreSQL 18 explanation are primary-source synthesis. A separate native PostgreSQL 16.15 supplement records ten prescribed cases in two same-host/build clusters; not a general conformance test or independent replication.

JSON: /data/terms/read-committed-isolation.json

Published by Hesela team · Updated

Report a correction · Editorial standards · Reuse guidance

Cite this page
Hesela team. Read Committed isolation. Hesela. 2026-11-13. https://hesela.dev/terms/read-committed-isolation/