Stage 5 · L53
Enforce capacity under concurrent requests
Core · original Session 5
Stock is the total rentable units of an item. Allocation is the sum of quantity on active rentals. Availability is stock minus allocation. A request is admissible only if its positive quantity fits that difference and the item is available rather than under maintenance. These are business rules beyond Pydantic's integer-range validation.
Within one transaction, reserve selects the equipment row FOR UPDATE before summing active allocations. Every reservation path must use that same lock. A competing request waits; after the first commits, the next sum sees its active rental under PostgreSQL's default Read Committed behavior and rejects excess demand. Checking the sum before taking the lock would reintroduce the race.
The concurrent fixture synchronizes two client threads at a barrier, each requesting quantity2 from stock2. Exactly one response must be201 and one409. A fresh session then checks active quantity equals2. This is real PostgreSQL coordination, not a dictionary simulation or an assertion that a mock rollback was called.
This rule assumes all writes that allocate stock follow the coordinated service. A separate SQL writer can violate a cross-row sum rule unless it uses the same policy or an additional database mechanism. The quantity CHECK ensures each rental is positive; it does not enforce aggregate capacity. State the invariant and its permitted writers together.
Follow the running code
Focused lesson example; see the end-of-stage capstone for the cumulative app · stage 05
Lock equipment row → read current active allocation
If maintenance or allocated + requested > stock: reject
Otherwise insert active rental and commit
Next waiter sees the new committed allocation.Predict and observe this focused example using the concepts explained above. Its boundary is stated in the focused answer.
Guided lab
- Read the explanation and predict the focused example’s outcome.
- Two requests each ask for quantity2 from stock2. Explain which row both writers must lock and the permitted outcomes.
- Compare the observed outcome with the focused answer and state its boundary.
Expected: Both reservation paths lock the same equipment row before summing active allocation. One inserts and commits; the next sees allocation2 and conflicts, so responses are201 and409 and total remains2. A transaction without that shared coordination can let both read stale capacity. Maintenance rejects without an insert.
- A transaction without the shared lock can over-allocate; per-row CHECK constraints do not enforce a cross-row sum.
Focused exercise and answer
Complete this focused exercise before reading its answer. The full native transfer is introduced only at the end of the stage.
Your transfer task: Two requests each ask for quantity2 from stock2. Explain which row both writers must lock and the permitted outcomes.
- Two requests each ask for quantity2 from stock2. Explain which row both writers must lock and the permitted outcomes.
Inspect the matching answer
This answer addresses the focused exercise above; the cumulative implementation is shown only after the stage prerequisites.
Both reservation paths lock the same equipment row before summing active allocation. One inserts and commits; the next sees allocation2 and conflicts, so responses are201 and409 and total remains2. A transaction without that shared coordination can let both read stale capacity. Maintenance rejects without an insert.Check your reasoning
What must every stock-allocating writer do?
Show the explanation
Coordinate on the same equipment row before calculating capacity and committing a rental.
Reading progress
54 lessons remain open to guests. Marking a lesson read records reading only; it does not award assessment credit or a certificate.
Device reading marks require browser storage. Reading is always available.
Sign in or create an account to save separate account progress. Your current page is kept.
Your earlier place on this device suggests these lessons. No new lesson is marked read.