Transaction atomicity enforced
Why it matters
Booking creation typically writes to multiple tables: the booking record, the slot's capacity counter, a payment reference, and possibly an audit log. Sequential await db.*.create/update calls outside a transaction are not atomic — if any step fails, all previous writes remain committed. CWE-362 and CWE-841 both apply: partial writes leave orphaned booking records with no slot decrement, or a slot marked unavailable with no corresponding booking. These orphaned records accumulate silently and are only discovered when a customer reports a missing booking or a slot appears permanently blocked.
Severity rationale
Critical because non-atomic multi-table writes produce orphaned records on partial failure, causing silent data corruption that is difficult to detect and expensive to remediate.
Remediation
Wrap every multi-table mutation in a single transaction in your booking service (e.g., src/lib/booking-service.ts). All writes succeed together or none does.
await db.$transaction([
db.booking.create({ data: { ...bookingData, status: 'CONFIRMED' } }),
db.slot.update({
where: { id: slotId },
data: { bookedCount: { increment: 1 } }
}),
]);
DetectionPro
The detection method for this pattern is part of AuditBuffet Pro.
The full method (what to look for, pass and fail conditions, and how results get reported) ships inside the Booking Flow & Lifecycle Audit. The pattern definition, severity rationale, and remediation remain openly licensed under CC-BY-4.0.
External references
- cwe · CWE-362 — Concurrent Execution Using Shared Resource with Improper Synchronization
- cwe · CWE-841 — Improper Enforcement of Behavioral Workflow
- owasp:2021 · A04 — Insecure Design
- iso-25010:2011 · functional-suitability.functional-correctness
Taxons
History
- 2026-04-18·v1.0.0·Initial import from booking-flow-lifecycle·automated