generated from bisco/codex-bootstrap
30 lines
1.3 KiB
Markdown
30 lines
1.3 KiB
Markdown
# ADR-0005: Prevent Overbooking with Database Transactions
|
|
|
|
Date: 2026-04-28
|
|
|
|
## Status
|
|
|
|
Accepted
|
|
|
|
## Context
|
|
|
|
AzioneLab allows multiple visitors to create pending reservations for the same performance. Pending reservations do not guarantee seats, so final capacity must be enforced when a reservation is confirmed.
|
|
|
|
Concurrent confirmation requests could otherwise read the same availability and confirm more seats than the performance allows.
|
|
|
|
## Decision
|
|
|
|
Use PostgreSQL transactions and Django ORM row-level locking to serialize capacity checks for a performance.
|
|
|
|
When creating or confirming a reservation, the backend locks the related `Performance` row with `select_for_update()`, recalculates confirmed seats server-side, and proceeds only if enough seats remain.
|
|
|
|
Confirmation performs the final capacity check inside the transaction before changing the reservation to `confirmed` and consuming the confirmation token.
|
|
|
|
## Consequences
|
|
|
|
- Capacity is enforced by the backend and database, not by frontend availability values.
|
|
- Concurrent confirmations for the same performance are serialized by the locked `Performance` row.
|
|
- Pending reservations can exceed current availability, but only confirmed reservations consume seats.
|
|
- The design stays simple and works with Django ORM and PostgreSQL.
|
|
- Very busy booking moments may queue briefly on the performance row lock.
|