Two-phase locking across shards
Connect conflict serializability, lock lifetime, atomic commit, and predicate protection without confusing 2PL with 2PC.
On this page
The question for today
What you’ll understand
- Distinguish lock acquisition/release phases from atomic-commit phases.
- Explain strict lock retention through a distributed outcome.
- Estimate a hot-record throughput ceiling from exclusive hold time.
A transaction updates one record on each of two shards and keeps both exclusive locks while its coordinator decides commit. The lock manager and commit coordinator are solving different problems, yet their lifetimes interact directly. Understanding that interaction explains both the isolation guarantee and the latency amplification caused by a slow participant. It also prevents a common naming mistake: two-phase locking is not two-phase commit.
The phases describe lock behavior
In basic two-phase locking, a transaction has a growing phase in which it acquires locks and a shrinking phase in which it releases them; after releasing a lock it must not acquire another. Under the appropriate conflict model, this discipline yields conflict-serializable schedules. Strict two-phase locking additionally keeps exclusive write locks until commit or abort, preventing other transactions from observing or overwriting those uncommitted effects. A stronger rigorous variant holds shared locks as well until completion; terminology varies, so state the exact retention rule.
Two-phase commit, in contrast, coordinates prepare votes and a final outcome among participants. A distributed system can use both: locks protect isolation while the commit protocol preserves atomic agreement. When a participant prepares, it may have to retain its locks until the global decision is learned. Releasing an exclusive lock early because its local computation is finished can let another transaction depend on an effect whose global outcome is unresolved. The correctness argument must connect lock release to the protocol’s valid completion boundary.
Protect predicates and use a global policy
Locking only rows currently returned by a query does not necessarily prevent a new row from satisfying that query later. A serializable locking design may need range or predicate protection covering the decision the transaction made. The exact supported mechanism depends on the database and access path. Do not infer that issuing SELECT FOR UPDATE on returned rows automatically protects every business condition. Test empty result sets, concurrent insertions, deletes, and changes that move records into a protected predicate.
A consistent lock acquisition order across shards can prevent certain cycles if every relevant transaction follows it, including upgrades and ancillary resources. A local order applied independently at each shard may still permit a global cycle when transactions contact shards in different orders. Deadlock detection and bounded retry remain important when the prevention assumptions are incomplete. A prepared transaction’s locks cannot be resolved solely by a local victim heuristic; the commit protocol constrains what outcome is still legal.
The network can lengthen a local lock
Break hold time into useful local execution and time retained for dependencies, prepare persistence, and decision delivery. Improving local CPU work may barely change the total if distributed waiting dominates. Measure the distribution of lock-hold duration and wait age by record or tenant, while observing which remote stage extends it. Avoid making network requests to unrelated services while holding transaction locks unless the design explicitly accounts for that cost and failure behavior. Admission control can prevent a hotspot from consuming every connection with waiting transactions.
The queue lab offers a capacity analogy for that hotspot. Reset, set arrival rate to 4 and service rate to 3, predict backlog at one second, then Step twice. Compare a new run after Reset with both rates explicitly set to 2 and 3, predicting before two Steps. The initial backlog is four abstract jobs in each run. This model does not implement locks, 2PL phases, deadlock, or commit; explain why reducing an exclusive hold time can raise a real service ceiling, while merely admitting more waiters cannot.
Work it through
Count the distributed contention footprint
Every transaction needs the same exclusive hot-record lock. Local work takes 2 milliseconds, prepare and decision waiting add 8 milliseconds, and completion processing before release takes 2 milliseconds. Assume consecutive owners and no overlap of incompatible ownership.
Add all periods during which the lock remains owned: 2 + 8 + 2 = 12 milliseconds, or 0.012 seconds per transaction.
The ideal hot-record ceiling is 1/0.012, approximately 83.33 transactions per second. Counting only the 2-millisecond local work would incorrectly suggest 500.
If local work is halved to 1 millisecond while all other periods stay fixed, hold time becomes 11 milliseconds and the ceiling becomes about 90.91 transactions per second, not 166.67.
Distributed waiting dominates this example. Halving one local stage improves the ideal ceiling by about 9.1%, illustrating why hold-time decomposition matters.
The living notebook
Explore the model
Interactive lab · queue
A hot lock limits draining capacity
Reset, set arrival rate λ = 4 and service rate μ = 3, predict the one-second backlog, then Step twice. Compare a fresh Reset with both λ = 2 and μ = 3, predicting before two Steps. This fluid illustration contains no lock manager or commit protocol.
- Fluid backlog
- 4
- Net rate · λ − μ
- −1 /s
- M/M/1 mean residence
- 1 s
Fluid backlog starts at 4 and follows max(0, 4 + (λ − μ)t). The separate M/M/1 residence-time formula assumes Poisson arrivals, exponential service and λ < μ. Parameter changes pause playback and recompute the model at the current elapsed time. Reset restores both parameters and returns time to zero. Playback starts paused. Adjust either parameter, then choose Play or Step.
Look forMore waiting transactions cannot exceed an exclusive resource’s sustained service capacity.
Pause & reason
Check your understanding
Your turn
Try it yourself
A hot exclusive record is held for 5 milliseconds of local work and 15 milliseconds of distributed waiting. Find its ideal serial ownership ceiling. Recompute if waiting falls to 5 milliseconds, and identify one condition that makes the calculation an upper bound rather than a measured prediction.
Take a moment to make a prediction or work it out on paper. Open a hint when you need one.
Give me a hint
Convert the complete hold interval to seconds before taking its reciprocal.
Compare with the solution
Initially h = 20 milliseconds = 0.020 seconds, giving at most 50 transactions per second. With waiting reduced, h = 10 milliseconds and the ideal ceiling is 100. Scheduling gaps, extra lock-manager overhead, failures, or another bottleneck can reduce measured throughput. The bound assumes every transaction needs that incompatible lock and that ownership cannot overlap.
Keep the idea
Take it with you
- 2PL’s phases concern acquiring and releasing locks; 2PC’s phases concern agreement.
- Strict lock retention and predicate coverage are explicit parts of isolation.
- Distributed decision latency can dominate a hot record’s contention footprint.
Read further
Original sources and deeper explanations to follow at your own pace.
Optional progress, saved in this browser when available. Revisit any lesson at any time.
Lesson not marked complete.