#014 HOW to DESIGN to prevent DOUBLE-BOOKING ?
Double Booking is very common design challenge
🎭 The Great Ticket Tussle 2.0: Alice, Bob & the Distributed Seat War
🧩 Act 1: Race Condition Rumble — “Threads Gone Wild”
Our heroes, Alice and Bob, hit “Book Seat” at the same millisecond.
The Booking API spawns two HTTP threads that race faster than Kafka consumers at a Black Friday sale.
Each performs:
SELECT * FROM seats WHERE id=42 AND status=’AVAILABLE’;
Both get AVAILABLE, both shout MINE!, and both attempt:
UPDATE seats SET status=’BOOKED’ WHERE id=42;
The DB, being a naive peacekeeper, says “Sure!” twice — and now both think they’ve won.
Boom 💥 — we’ve entered a distributed race condition with write-write conflict.
Moral: Without concurrency control, your database becomes a double-booking DJ spinning chaos.
🔒 Act 2: The Grumpy DBA — Pessimistic Locking
Enter Mr. Pessimistic Lock, the gatekeeper DBA with a giant FOR UPDATE hammer.
He growls:
“No thread shall pass until I COMMIT or ROLLBACK!”
Alice grabs the lock — Bob’s transaction hits the waiting queue like a traffic jam on the I/O freeway.
✅ Guarantees mutual exclusion (mutex at the DB row level).
❌ But under 100K RPS (requests per second), throughput nosedives faster than a dead index scan.
Deadlocks appear like surprise guests at a production outage.
Moral: Strong consistency, weak scalability — like one bathroom in a stadium.
🧘♀️ Act 3: The Zen Dev — Optimistic Locking
Then floats in Ms. Optimistic Lock, barefoot, holding a “version column” scroll and sipping kombucha.
She believes in Compare-And-Swap karma:
“Trust the version, but verify before update.”
Each record has a version_number. The update query now looks like:
UPDATE seats
SET status=’BOOKED’, version=version+1
WHERE id=42 AND version=5;
If someone else changed it, her update fails gracefully. No blocking, no waiting — just zen retries.
✅ Great for OLTP workloads with low contention.
❌ But on high-demand events (like Coldplay tickets), it causes a retry storm that melts your CPU faster than a runaway while(true) loop.
Moral: Optimism is nice, until everyone’s optimistic at once.
⚡ Act 4: Redis the Hyperactive Squirrel — In-Memory Distributed Lock
Enter Redis the Caffeinated Squirrel, running on a hamster wheel labeled:
SETNX lock:seat:42 “Alice” EX 5
He handles locks in RAM — lightning-fast, ephemeral, and full of energy drinks.
He squeaks:
“I’ll keep it safe in memory, promise!”
✅ Low latency (microseconds) and massive concurrency.
❌ But if Redis crashes, all locks go poof — and chaos resumes like unbounded fan-out in a gossip protocol.
So engineers add replicas, RedLock algorithm, and TTL expiry to avoid ghost locks.
Still, Redis occasionally forgets who owns what — like a squirrel misplacing nuts.
Moral: Fast isn’t free — distributed locking is just latency with better PR.
🎟️ Act 5: The Zen Queue Master — Virtual Waiting Queue
Then arrives Kafka, the wise juggler, alongside RabbitMQ, his calm assistant.
Together they set up a FIFO buffer called the Virtual Waiting Queue.
When traffic spikes above 10K RPS, they say:
“One at a time, mortals. Your request has been enqueued.”
Each booking becomes an event consumed asynchronously.
Users watch a Server-Sent Events (SSE) dashboard that says “⏳ You’re #12,347 in line.”
✅ Scales elastically with backpressure control.
✅ Prevents cascading failures across caches and DB.
❌ But adds operational pain — now you’re managing Kafka clusters, retries, dead-letter topics, and your devops engineer cries softly into their YAML.
Moral: Queues save systems, but ruin weekends.
☁️ Final Act: The Cloud Architect’s Moral
From his Kubernetes throne, the architect declares:
“All consistency models bow to CAP. Thou shalt choose between availability and sanity.”
Pessimistic Locking → ACID purist, hates concurrency.
Optimistic Locking → Believes in second chances, causes retries.
Redis Locking → High-speed chaos control with amnesia.
Virtual Queue → Orderly chaos, but ops-heavy.
In the end, every booking system is a balancing act between latency, throughput, consistency, and developer tears.

