← Selected work Catalog Order Service / Case study Source ↗

Catalog Order Service

One last unit. One winning order.

Live · 44 tests · Updated 2026

Java 21 · Spring Boot · Spring JDBC · H2 · JUnit 5

Hosted on Render. The first open may take up to about 60 seconds; the proof below remains available immediately.

Context
Independent systems project · 2026
My role
Designer and sole engineer
Team
Solo build
Evidence
44 tests · two-thread stock race

two threads · product 4 · stock 1

{ "successfulDeductions": 1, "rejectedDeductions": 1, "stockQuantity": 0 }

Checkout looks simple until two buyers want the last unit, a client retries after a timeout, or item three fails after items one and two already changed stock.

Failure

  • Two buyers race for the last unit.

    Exactly one conditional UPDATE succeeds. Stock finishes at zero, never negative.

  • The client retries with the same key.

    The original order returns with 200; stock is not deducted again.

  • A later line item is out of stock.

    The transaction rolls back the order and every earlier deduction.

  • Two requests ship the same order.

    Only CREATED can become SHIPPED; the loser receives 409.

  • The webhook endpoint keeps failing.

    Delivery stops after three attempts; the committed shipment remains shipped.

Inspect

Live Open product ↗

Source GitHub ↗

Wake time Allow up to about 60 seconds on the first request.

What I would improve next

  1. Move the demo from embedded H2 to PostgreSQL with versioned migrations and production query plans.
  2. Replace in-process webhook retry with a transactional outbox and durable worker queue.
  3. Add payload fingerprints, stronger client identity, URL allowlisting, and operator-facing redrive tooling.