Dealing with Contention
- Fix race conditions with atomicity, locks, or optimistic concurrency. Scale to distributed coordination when needed.
30-second elevator pitch: "Contention happens when two users act on the same data at once - like two people buying the last concert ticket. I fix it by making operations atomic, using locks when conflicts are common, or optimistic concurrency when they are rare. For distributed systems, I use sagas or two-phase commit."
The Problem
Consider buying concert tickets online. There is 1 seat left. Alice and Bob both click "Buy Now" at the same moment. Without coordination, both read "1 seat available," both proceed to payment, and both get the same seat. One gets kicked out at the door.
The race condition happens because both read the same initial state before either write takes effect. There is a gap between "check" and "update" where the world can change. With 10,000 concurrent users, even tiny windows create massive conflicts.
3 problems that use this pattern: Ticketmaster, Rate Limiter, Online Auction.
What You Will Learn
Single-node solutions
- Atomicity and transactions (all-or-nothing)
- Pessimistic locking (FOR UPDATE, lock first)
- Isolation levels (READ COMMITTED, SERIALIZABLE)
- Optimistic concurrency (version numbers, retry on conflict)
>
Distributed coordination
- Two-phase commit (2PC) for strong consistency
- Sagas for eventual consistency with compensation
>
Deep Dives
- When to use pessimistic vs optimistic
- How sagas handle partial failures
- Deadlock detection and avoidance
The Solution: Escalation Path
What interviewers want to hear: "I start with atomic transactions. If contention is high, I use pessimistic locking. If it is low, optimistic concurrency is faster. For distributed systems, I prefer sagas over 2PC when I can tolerate eventual consistency."
Single-node Solutions
Atomicity
Atomicity means a group of operations either all succeed or all fail. No partial completion. Transactions provide this: BEGIN, do work, COMMIT or ROLLBACK.
For the concert ticket: decrement seats and create a ticket record in one transaction. If anything fails, both roll back. The database ensures no orphaned ticket without a seat.
Interview tip: Always mention transactions when multiple related writes must stay consistent.
Pessimistic Locking
Pessimistic locking assumes conflicts will happen and prevents them up front. Lock the row with SELECT FOR UPDATE before updating. Alice's transaction acquires the lock; Bob blocks until Alice commits.
Lock as few rows as possible, for as short a time as possible
Hold locks for milliseconds, not seconds
Without lock - Both read seats = 1, both decrement. Result: -1 seats, double sale.
With FOR UPDATE - First transaction locks row; second waits. Only one sale.
Optimistic Concurrency
Optimistic concurrency assumes conflicts are rare. Add a version column. When updating, include "WHERE version = 42" in the UPDATE. If someone else updated first, zero rows match. Check affected rows; if zero, retry or report conflict.
Better under low contention: no blocking
Must handle retries in application code
Interview tip: Use optimistic when conflicts are rare (most users hit different rows). Use pessimistic when many users compete for the same row (last ticket, auction close).
Distributed Coordination
Two-phase Commit (2PC)
When data spans multiple databases, 2PC coordinates: prepare phase (all say "ready"), then commit phase (all commit or all abort). Strong consistency, but blocks on any failure. Used when you need ACID across services.
Sagas
Sagas break the flow into steps. Each step is a local transaction. If a later step fails, run compensating transactions (refund payment, release inventory). No distributed locks - eventually consistent.
Use when you can tolerate temporary inconsistency
Requires careful compensation logic
When to Use in Interviews
Use contention solutions when the problem involves: limited inventory, auction bids, rate limiting, or any "check-then-act" on shared state. Ticketmaster, online auctions, and inventory systems are classic.
When NOT to use: Simple CRUD with no concurrency. Single-writer systems. Read-heavy workloads with no conflicting writes.
Summary
Atomicity - Transactions for single-DB consistency
Pessimistic - Lock first when conflicts are common
Optimistic - Version check when conflicts are rare
Distributed - 2PC for strong consistency; sagas for eventual consistency with compensation
{{SUBSCRIBE}}
{{BUTTON:Read More Articles|https://systemdesignlaws.xyz}}


