JAlcocerTech E-books

Advanced: Transactions and Consistency

Transactions are an abstraction for grouping operations so applications can reason about correctness despite failures and concurrency.

ACID

ACID is a useful label but not a complete specification.

  • Atomicity: a transaction commits or aborts as a unit.
  • Consistency: application-defined invariants are preserved if the transaction logic is correct.
  • Isolation: concurrent transactions behave as if separated according to some isolation model.
  • Durability: committed data survives failures the database promises to tolerate.

The details matter more than the acronym.

Isolation Levels

Weak isolation is common because full serializability can be expensive. But weak isolation admits anomalies.

Read committed prevents dirty reads and dirty writes. Snapshot isolation gives each transaction a consistent snapshot, often through multi-version concurrency control. Serializable isolation aims to make concurrent transactions equivalent to some serial order.

Common Anomalies

Important anomalies include:

  • lost updates
  • dirty reads
  • non-repeatable reads
  • write skew
  • phantoms

Write skew is especially dangerous because each transaction can make a locally reasonable decision from a snapshot, while the combination violates an invariant.

Serializability

Serializability is the strongest common isolation model. It can be implemented through actual serial execution, two-phase locking, or optimistic techniques such as serializable snapshot isolation.

The design choice is a tradeoff among correctness guarantees, contention, latency, throughput, and operational complexity.

Distributed Consistency

Consistency across replicas is different from transaction isolation. Linearizability means operations appear to take effect atomically at one point in time. It is intuitive and strong, but expensive in distributed systems because coordination is required.

Causal consistency is weaker but often useful: if one operation causally depends on another, all observers should respect that order.

Practical Takeaway

Do not treat “transactional” as a yes/no property. Ask:

  • what isolation level is actually used?
  • what invariants must be protected?
  • can two users pass the same check concurrently?
  • does this operation span partitions or services?
  • are retries safe?
  • does the application need serializability, linearizability, or something weaker?