What's happening?
- Without protection, both requests check that the slot is free before either has written, so both book it.
- With a lock, the second request waits until the first has finished, then sees the slot is taken.
- With a unique constraint, the database itself refuses the second booking, whatever the timing.
Where you'll meet it
Booking seats and appointments, wallet balances, stock counts, coupon redemptions — anything where two users can change the same thing at once.
Common mistake
Checking "is it free?" in code and then inserting, as two separate steps. Each step is correct; the gap between them is the bug.
FAQ
Why don't tests catch race conditions?
Tests usually send one request at a time. The bug only shows when requests overlap, which happens under real traffic.
Lock or unique constraint — which is better?
A unique constraint is the last line of defence and cannot be bypassed; a lock lets you check business rules safely. Production systems often use both.
What should the API return to the loser?
A clear conflict — HTTP 409 — so the client can tell the user the slot was just taken.