Checkout Race-Condition Case Study

Checkout combines browser actions, inventory, payment, orders, caches, and asynchronous messages into one concurrency-sensitive workflow.

Why This Matters

No single lock spans every system safely. The design needs local transactions, stable operation IDs, explicit states, and compensating or retryable steps.

Working Model

Checkout combines browser actions, inventory, payment, orders, caches, and asynchronous messages into one concurrency-sensitive workflow. Correctness comes from preserving an explicit invariant across every permitted ordering, not from expecting one observed timing.

Practical Rules

  • Create one checkout operation ID.
  • Reserve inventory atomically.
  • Persist order state transitions.
  • Call payment with provider idempotency.
  • Publish durable follow-up work through an outbox.

Failure Modes

  • Charging before durable order identity exists.
  • Holding database locks across payment calls.
  • Treating timeout as payment failure.
  • Sending email directly inside the order transaction.

Verification

  • Double-submit and multi-tab checkout.
  • Drop payment responses.
  • Crash before message publication.
  • Expire and release reservations.

What You Should Be Able To Do

After this lesson, you should be able to explain an end-to-end race-resistant checkout across browser, PHP, database, cache, payment, and queue boundaries, choose a suitable approach for a real PHP project, and verify the result instead of relying on assumptions.

Practice

Practice: Design Checkout States

Define durable states for a retryable checkout.

Your answer must:

  • state the intended outcome;
  • show the commands, data flow, or implementation shape;
  • identify at least one unsafe alternative;
  • explain how the result will be verified.
Show solution

Use explicit states such as pending, inventory_reserved, payment_pending, paid, failed, and expired with guarded transitions and recorded operation IDs.

The important part is not memorising one command or vendor screen. The solution makes the invariant, failure behavior, and verification evidence explicit.

Practice: Handle Payment Timeout

Payment times out after the provider may have charged.

Your answer must:

  • state the intended outcome;
  • show the commands, data flow, or implementation shape;
  • identify at least one unsafe alternative;
  • explain how the result will be verified.
Show solution

Keep the order pending, query or retry with the same provider idempotency key, and never create a second charge from a new key.

The important part is not memorising one command or vendor screen. The solution makes the invariant, failure behavior, and verification evidence explicit.

Practice: Publish Order Events

Guarantee that paid orders eventually emit follow-up work.

Your answer must:

  • state the intended outcome;
  • show the commands, data flow, or implementation shape;
  • identify at least one unsafe alternative;
  • explain how the result will be verified.
Show solution

Write an outbox event in the same database transaction as the paid transition. A retrying publisher sends it, and consumers deduplicate by event ID.

The important part is not memorising one command or vendor screen. The solution makes the invariant, failure behavior, and verification evidence explicit.