Concurrency Problems

1.The Flash Sale That Broke Everything

M

In this chapter

GreenMart's flash sale oversold its last item to two customers at once — we'll see exactly why "check, then act" breaks the moment more than one customer acts at the same time, without a single line of code ever being wrong on its own.

12–15 min

The Problem in Real Life

GreenMart's website has been live for weeks, and today Mike launches a flash sale: one shipment of discounted rice, first come first served. Within seconds of going live, dozens of customers hit "Buy" at almost the exact same moment.

By the time Sarah checks the dashboard, the numbers don't make sense: two separate orders for the very last bag, and InStock sitting at -1. Nothing crashed. No error was ever thrown. The database did exactly what it was told — twice, at the same time.

S

It sold the same last item to two different people. How is that even possible?

Sarah

One Customer at a Time vs. Everyone at Once

Correct code, wrong timing

Every statement ran correctly and returned a true answer for the instant it ran — the bug lives in the gap between two statements, not inside either one.

More customers means more collisions, not more bugs

The exact same code ran flawlessly for weeks with one customer at a time; the flash sale just made simultaneous checkouts common instead of rare.

"Check, then act" is inherently risky

Any pattern that reads a value, decides something based on it, and writes a result later is vulnerable the moment two requests can overlap.

No error, no warning, just a wrong answer

Nothing crashed and nothing logged a problem — the database just quietly did exactly what it was told, twice.

What Is a Concurrency Problem, Really?

Every query in this course so far has run alone — one statement, finished, before the next one starts. A real website never works that way: dozens, sometimes thousands, of requests can hit the database in the exact same instant, each one completely unaware the others exist.

The bug in the flash sale isn't a typo or a missing WHERE clause. It's a race condition — a bug that exists because of when things happen, not what they say. The exact same code, run one customer at a time, would have worked perfectly.

How Two Customers Both "Win" the Last Item

Customer A

Reads InStock = 1

Customer B

Reads InStock = 1

both checks happen before either write

Customer A

Sees it's available, proceeds

Customer B

Sees it's available, proceeds

both proceed to write

Customer A

INSERT Sale, sets InStock = 0

Customer B

INSERT Sale, sets InStock = -1

result

Two sales recorded for one item that only existed once

This is the obvious way to write "only sell it if it's still in stock" — check first, then act. Run once, by itself, it's completely correct.

The Naive "Check, Then Act" Logic
-- Step 1: check if it's still in stock
SELECT InStock FROM Products WHERE ProductID = 5;
-- Step 2: if InStock > 0, record the sale and decrement it
INSERT INTO Sales (SaleID, CustomerID, ProductID, SaleDate) VALUES (215, 108, 5, '2026-08-29');
UPDATE Products SET InStock = InStock - 1 WHERE ProductID = 5;

Run twice, by two different customers at nearly the same instant, both checks can see the same "1 left" before either customer's update has actually happened — and both proceed to sell it.

Notice that nothing here was technically wrong — every individual statement ran correctly, returned the right answer for the exact instant it ran, and never threw an error. The bug lives only in the gap between reading a value and acting on it, a gap that's invisible when one customer is checking out, and very real when hundreds are.

GreenMart needs a way to make "check, then act" happen as one uninterruptible step, not two separate ones a stranger's request can slip in between. That's exactly what the next chapter is about.

Key Takeaway

A race condition happens when the timing of two operations, not their logic, causes a wrong result — the exact same code that works perfectly for one customer at a time can silently break the moment two run at once.

Why This Matters

Every real system with more than one user at a time has this exact class of bug waiting somewhere — inventory counts, seat bookings, account balances, like counts. Recognizing "check, then act" as inherently dangerous, before it ships, is one of the most valuable instincts a working developer can build.

GreenMart finally understands what actually went wrong during the flash sale. Fixing it for good is the next chapter's job.

Next