All-or-none claim
Claim exactly N rows or none. A dispatcher that needs four free stations either locks four or locks nothing and tries again.
The situation
A dispatcher has claimed four orders and needs four ready stations to run them. Locking three would strand the fourth order and hold three stations that cannot be used as a set.
The recipe
const { data } = await lt.escalations.claimByFacets({ query: { role: 'stations', facets: { state: 'ready', material: 'steel' } }, limit: 4, durationMinutes: 30, allOrNone: true,});if (!data?.claimed.length) { // fewer than four were free: nothing was locked}ltc esc claim-by-facets --role stations --facets '{"state":"ready"}' --limit 4 --all-or-noneWithout allOrNone, the call locks up to limit available rows in rank order. With it, the transaction commits only when the full limit is acquired.
The guarantee
On a shortfall the transaction rolls back and returns an empty set, so no row is left half-held. Rows are taken with FOR UPDATE SKIP LOCKED, so a competing dispatcher skips rows already locked rather than waiting on them. See Faceted routing.
Related patterns
The queue as a market
Claim complete groups
A consumer claims whole orders, every unit at once, and only orders whose units have all arrived. No order is ever split across consumers.
The queue as a market
Two-sided dispatcher
Demand and supply are both rows. A dispatcher counts free supply, claims that much demand, locks the supply all-or-none, and pairs them.
Resolving from anywhere
Resolve a set, all or none
Each row in a set resolves with its own payload in one statement, waking each workflow with its own value, or nothing resolves.
The queue as a market
Availability is a query
A row is held only while its claim window is live. Availability is computed at read time, so no job has to flip a flag back.
