//ticket-servicebyiiio2

ticket-service

0
0
0
1
TypeScript

Ticket Service Bug Analysis & Fix

The Bug

A race condition in purchaseTickets() causes two symptoms:

  1. undefinedOverselling — The availability check (SELECT) and decrement (UPDATE) are separate, non-transactional queries. Concurrent requests all read the same available value, all pass the check, and all decrement — pushing available negative.

  2. undefinedDuplicate ticket numbers — Ticket numbers are computed from the same stale snapshot (total - available), so concurrent requests generate identical ranges. No UNIQUE constraint existed to catch this.

The Fix

  • Wrapped all queries in a transaction with SELECT ... FOR UPDATE to lock the event row and serialize concurrent access
  • Replaced N individual INSERTs with a single batch INSERT
  • Added UNIQUE (event_id, ticket_number) and CHECK (available >= 0) constraints to init.sql

Reproduction

npm run reproduce — fires 10 concurrent requests against 32 available tickets to demonstrate both issues.

[beta]v0.14.0