Concurrent execution with a serial explanation

Transactions may interleave while still producing effects equivalent to some serial order. The requirement constrains acceptable outcomes, not the physical arrangement of all execution into a single queue.

A complete snapshot alone does not establish this property. Two transactions can each read stable data yet make mutually dependent decisions whose combined committed result has no possible one-at-a-time explanation.

References: [1]

Conflicts can span different rows

Suppose a and b initially equal one. Transaction A sets a to zero only after reading b as one; B sets b to zero only after reading a as one. If both commit from their old snapshots, both values become zero.

In either serial order, the second transaction would see the first change and its condition would fail. This hypothetical example shows why preventing simultaneous overwrites of the same row is insufficient: dependencies can connect reads and writes across rows.

References: [1]

Detection and retry complete the guarantee

PostgreSQL Serializable Snapshot Isolation monitors dependencies in addition to providing snapshots and can abort a transaction to prevent an anomaly. Its dependency-tracking predicate locks do not act as ordinary blocking exclusive locks.

Applications must retry the complete rejected transaction, including the reads supporting its decisions. Results from an uncommitted attempt cannot safely be treated as irrevocable external facts. Rejection is part of enforcing the guarantee.

References: [1] [2]