Skip to content

Transaction Isolation

Concurrency-control protocol — instantiates Shared-State Consistency Contract Design

Defines which concurrency anomalies a multi-operation transaction is protected from by naming an isolation level and the set of interleavings it rules out.

Transaction Isolation defines what a transaction — a group of reads and writes treated as one unit — is allowed to see of other transactions running at the same time. Its distinguishing contribution to the contract is that it states the guarantee as a named isolation level whose meaning is precisely the set of anomalies it forbids: dirty reads, non-repeatable reads, phantoms, write skew, lost updates. Rather than promising a vague "transactions don't interfere," it commits to an exact frontier — these interleavings are legal, those are not — and everything the level rules out will never be observed, even under concurrency.

Example

Two holders of a joint checking account each open the mobile app at the same moment; the balance is $100. Each initiates a $70 withdrawal. Under Read Committed isolation, each transaction reads $100, checks "≥ withdrawal? yes," and writes $30 — and both commit, overdrawing the account to −$40. This is the classic lost update / write-skew hazard: neither transaction saw the other's read-then-write. Raising the account service to Serializable isolation forces the two into an equivalent-to-serial order: one reads $100 and commits $30; the second is made to see $30, fails its check, and aborts. The isolation level didn't change what a withdrawal does — it changed which concurrent histories the system will admit, ruling out the one where both succeed.

How it works

Isolation levels are defined not by an algorithm but by the anomalies they exclude; two-phase locking, snapshot isolation (MVCC), and optimistic concurrency control are different implementations of the same contract points. The mechanism's job in contract design is to (a) pick the weakest level that still rules out the anomalies the invariant cares about, and (b) make that level explicit per transaction, since one database routinely serves several. The formal frame is that each level names a class of legal histories — the schedules of interleaved operations considered equivalent to some serial execution, with serializability the strictest.

Tuning parameters

  • Isolation level — Read Committed → Snapshot/Repeatable Read → Serializable; higher rules out more anomalies but costs concurrency through more aborts or blocking.
  • Concurrency-control strategy — pessimistic locking (blocks, risks deadlock) vs. optimistic/MVCC (never blocks reads, aborts on conflict at commit). Same level, different latency and abort profile.
  • Predicate / range locking — whether phantoms over a query range are prevented; required for serializable, expensive on hot ranges.
  • Per-transaction override — letting a read-only report run at a weaker level than a money-moving write, instead of one global setting.

When it helps, and when it misleads

Its strength is turning "don't corrupt the data" into a checkable, per-transaction guarantee with a well-understood cost. It misleads when teams read the label and not the anomaly list — and the labels drift: "Repeatable Read" in one engine is snapshot isolation that still permits write skew, so picking a level by name rather than by which anomaly threatens the invariant is the standard trap.[1] The classic misuse is cranking everything to Serializable "to be safe," then quietly dropping back under load without re-checking which invariant just lost its protection. The discipline is to derive the level from the specific anomaly the invariant forbids, and to verify behavior — not the label — against real interleavings.

How it implements the components

  • isolation_level — the mechanism is the choice and enforcement of a named level; that name is the client-visible guarantee.
  • legal_history_contract — a level is formally the set of interleaved histories it admits as equivalent-to-serial; isolation encodes exactly that set.

It governs multi-operation transactions, not the single-object read/write path: which replica serves a read is Bounded-Staleness Read Policy's, cross-session causal order is Causal-Consistency Protocol's, and detecting an actual violation in a recorded run is Consistency History Checker's.

References

[1] Serializability and the ANSI isolation levels — the standard levels are defined by which phenomena (dirty read, non-repeatable read, phantom) they prohibit. Later analysis (Berenson and colleagues' critique of the ANSI definitions) showed the definitions are ambiguous and that snapshot isolation permits write skew despite looking strong — which is why naming the anomaly, not the level, is the robust practice.