Reclaiming Serializability: The Story of SI, Serializable, and SSI
In the previous post, we looked under the hood at how databases enforce isolation through locks, validations, and snapshots.
Although these isolation levels were already introduced in the earlier post, we’ll revisit them here to clear up one of the most common sources of confusion i.e., the trio that sound deceptively similar: Snapshot Isolation (SI), Serializable Isolation, and Serializable Snapshot Isolation (SSI).
These three sit at the upper tier of the isolation hierarchy, each promising correctness with varying degrees of coordination. On paper, they look nearly identical; in practice, they differ deeply in what they guarantee and how much concurrency they allow.
Snapshot Isolation (SI): Consistency Without Coordination
Snapshot Isolation gives each transaction its own consistent view of the database, a snapshot frozen at the time the transaction begins.
How It Works
1. Each transaction reads from a snapshot taken at its start time.
2. Writers create new versions of modified rows (no overwrites).
3. At commit, the system checks for overlapping writes i.e., if two transactions updated the same row, one aborts.
This prevents dirty reads, non-repeatable reads, and phantoms, but still allows a subtle anomaly called write skew.
Serializable Isolation: The Gold Standard
Serializable isolation enforces the strictest guarantee i.e., every transaction behaves as if it ran alone in a serial sequence.
How It Works
There are two classic ways to implement it:
| Mechanism | How It Ensures Serializability |
|---|---|
| Two-Phase Locking (2PL) | Blocks conflicting reads/writes until commit. |
| Optimistic Concurrency Control (OCC) | Validates conflicts at commit and aborts if needed. |
Both methods eliminate all anomalies but restrict concurrency:
• PCC can lead to lock contention and deadlocks.
• OCC can lead to frequent aborts in high-conflict workloads.
| Anomalies Prevented | Still Possible |
|---|---|
| All | None |
Serializable isolation is correct but often overkill in systems optimised for throughput.
Serializable Snapshot Isolation (SSI): The Best of Both Worlds
To combine performance with correctness, modern systems introduced Serializable Snapshot Isolation (SSI). It builds on snapshot isolation but adds dependency tracking to detect hidden conflicts that snapshots alone miss.
How It Works
1. Every transaction runs under snapshot isolation given us fast, non-blocking reads.
2. The system tracks RW dependencies between concurrent transactions.
3. If those dependencies form a cycle, one transaction is aborted, ensuring the final order remains serializable.
| Dependency Example | Meaning |
|---|---|
| T1 -> T2 | T1 read something that T2 later modified. |
| T2 -> T3 | T2 read something that T3 later modified. |
| T3 -> T1 | Cycle detected -> abort one transaction. |
This cycle detection restores serializability without introducing locks.
| Anomalies Prevented | Still Possible |
|---|---|
| Dirty Read, Non-repeatable Read, Phantom Read, Write Skew | None |
SSI represents a quiet revolution in database design. SSI gives us the mental simplicity of sequential execution without the performance penalties of traditional locking. It ensures your application's data remains correct under all circumstances, even complex scenarios where weaker isolation levels might fail. It's not a silver bullet though. High contention workloads can lead to more transaction aborts and retries but for most modern applications, it strikes an excellent balance of safety and speed.
Summary Table
| Isolation Level | Prevents | Still Possible | Concurrency |
|---|---|---|---|
| Snapshot Isolation (SI) | Dirty, Non-repeatable, Phantom | Write Skew | High |
| Serializable Isolation | All | None | Low |
| Serializable Snapshot Isolation (SSI) | All | None | High |