17. Transactions and Locking
1
The picture to keep in your head2
17.1 What is a transaction?3
17.2 What does ACID mean in depth?4
17.3 What is a lost update?5
17.4 What can a transaction see that it shouldn't?6
17.5 What are isolation levels?7
17.6 What is pessimistic locking?8
17.7 What is optimistic locking?9
17.8 What is a deadlock?10
17.9 What are distributed locks, and why are they tricky?11
17.10 What is two-phase commit?12
17.11 What is a saga?13
17.12 How do seat holds with expiry work?14
Memory card and where the analogy breaks15
Practice: five levels16
Interview questions17
Solutions18
Sources19
Code lab17. Transactions and Locking
17.12 How do seat holds with expiry work?
3 min read+10 XP
On the train: "Seat 14 is held for you for 10 minutes. Pay by 10:12 or it goes back on sale." Nobody else can take it meanwhile, and nobody can hog it forever.
In the system: A hold (reservation) splits booking into two steps, so a user isn't racing others while typing card details:
free ──hold(user, expires = now + 10 min)──▶ held ──pay in time──▶ sold
▲ │
└────────── hold expires or user cancels ────┘
- Hold: atomically move the seat from
freetoheldwith the user and an expiry time (an atomic conditional update or a unique constraint makes sure only one hold wins). - Pay: the payment step checks the hold is still yours and not expired, then marks it
sold. - Expire: a background job (or a check on every read) returns expired holds to
free.
In the chapter's code, Ravi can't take seat 1 while Asha holds it; once her 10 minutes pass, Ravi gets it and Asha's late payment is refused.
Details that matter:
- Choose the hold time from how long payment really takes; too long and seats sit idle while real buyers are turned away.
- Use the database's clock, or one trusted clock, for expiry, not each app server's.
- Payment arriving just after expiry: decide the rule (refund automatically) and make it idempotent.
- Limit holds per user so bots can't hold every seat (Chapter 25).
Memory code: "Hold it, pay for it, or lose it."