Designing Data-Intensive Applications, session 10

Serializability,
three ways

The strongest isolation level, and what each implementation costs you.

→ next · ← back · N notes · F full screen

Why not just use serializable?

Weak isolation bugs are subtle, rare, and almost impossible to find by testing. Serializable means: the result is as if transactions ran one at a time.

The question is the price.

1
literally one at a time
2PL
pessimistic locking
SSI
optimistic, detect and abort
01

Actual serial execution

Just use one thread.

One thread, no concurrency, no anomalies.

Possible once RAM got cheap and OLTP transactions turned out to be short. VoltDB, Redis, and Datomic do this.

The catch: no waiting for the user mid-transaction. The whole transaction must be submitted at once as a stored procedure.

Interactive transactionStored procedure appDB appDB all logic
02

Two-phase locking

Readers block writers, writers block readers.

2PL: hold every lock until commit.

03

Serializable snapshot isolation

Go ahead optimistically. Check at commit.

Detect the conflict, abort, retry.

Built on snapshot isolation, plus tracking of stale reads and of writes that affect earlier reads. PostgreSQL since 9.1, FoundationDB.

Which one when?

Serial executionTwo-phase lockingSSI
ConcurrencyNone per partitionPessimisticOptimistic
Blocking✕ whole queue waits✕ readers and writers block✓ no blocking
Best forTiny, fast, in-memory transactionsShort transactions, low contentionLow contention, many readers
Main riskOne slow transaction stalls allLatency spikes, deadlocksHigh abort rate under contention

Now, our system.

Where would SERIALIZABLE pay off?

Which flows have check-then-act rules today? Would running just those at SERIALIZABLE remove whole classes of bugs?

Retry handling

Do we catch serialization failures and deadlocks (SQLSTATE 40001, 40P01) and retry safely?

Long transactions

Do any batch jobs hold a transaction open for minutes? They hurt every isolation strategy.

Locks we take

Where do we use FOR UPDATE or JPA pessimistic locks? Do we always lock in the same order to avoid deadlocks?

Next session

The trouble with distributed systems

Unreliable networks, unreliable clocks, and processes that pause without warning. Chapter 8.