The Lock That's Too Expensive to Hold

The textbook database answer to two people booking the same seat, and the math that proves you can never hold that lock for an entire payment flow.

August 30, 20263 min read7 / 25

That's the part that happens entirely on the backend, and it's next.

Two People, One Pay Button, Same Instant

Picture two people, P1 and P2, clicking pay at the exact same moment. P1 is booking seats 2 and 5. P2 is booking seats 5, 7, and 9.

Seat 5 overlaps. Only one of them can be let through to the payment screen.

The Textbook Answer: Serializable Isolation

Most relational databases have an isolation level called SERIALIZABLE. If two transactions try to touch the same row at the same time, it only lets one of them through. The other one waits.

If a query has been waiting too long, say a couple of seconds, the practical move is to just treat it as failed. Show the user an error and let them try again, rather than leaving them stuck wondering what happened.

This is worth knowing as a general database concept, useful well beyond this specific project.

Why Holding That Lock for Two Minutes Is a Disaster at Scale

Here's where it gets interesting. P1 wins the lock and gets taken to the payment screen. Card details, UPI, a countdown timer. On average, paying takes about two minutes.

So here's the real question: for how long should that database lock stay held? A tempting first answer is simple: keep it locked until payment succeeds, fails, or the person presses back.

That answer breaks the moment you look at the numbers.

Say 10,000 people are trying to book some seat, somewhere, at any given instant, which isn't unusual at BookMyShow's scale. Each one holds a lock for roughly two minutes while they pay. Multiply that out across a two-minute window, and you land somewhere around 100,000 separate locks open on the database at once.

A brief lock around checking seat status is fine, but holding that same lock for the entire two-minute payment flow multiplies into roughly 100,000 simultaneous locks at BookMyShow's scale ExpandA brief lock around checking seat status is fine, but holding that same lock for the entire two-minute payment flow multiplies into roughly 100,000 simultaneous locks at BookMyShow's scale

That many open locks makes the database slow. CPU usage climbs. Memory usage climbs. None of it helps anyone actually get their ticket faster.

A database lock should never be held for the length of an entire payment flow. Whatever the real answer turns out to be, it has to release that lock far sooner than "when the payment finishes."

The Algorithm So Far

Here's the shape of the book-ticket logic, as far as it goes before the lock question gets resolved:

  1. Get the requested seats.
  2. Check the status of each one.
  3. If any seat isn't available, stop immediately. Reject the whole booking.
  4. If every seat is available, proceed.

Steps one and two need to happen inside a lock. If P1 and P2 both read the same three seats as available at the same instant, before either has written anything, both will conclude the booking can go ahead. The read itself has to be protected, not just the eventual write.

That's the part that's already settled: a lock has to guard reading and checking the seats. What isn't settled yet is what happens after that check passes, once the database lock actually gets released, and how the seat still manages to stay off-limits to everyone else for the next two minutes without one.