Only a server that answered should spend a retry
A phone out of coverage for a day burned its retry budget on failed connections and parked a valid order as rejected. That is the loss a queue prevents.
Topic
What happens when the same thing arrives twice, and which of the two wins.
12 articles
Almost every article filed here starts the same way: something worked in testing and produced a duplicate in production. A payment provider sends two events for one payment. A queue redelivers. An operator reprocesses a batch. A client retries a request that had, in fact, succeeded. None of these are exotic, and a system that has not decided what it does about them has decided by accident.
The rule the collection keeps arriving at is that read-then-act is not a concurrency control, however careful the reading is. The condition has to be part of the write, and the caller that sees one affected row is the one allowed to continue. Everything else — uniqueness constraints, idempotency keys, replay-safe queues — is a backstop behind that.
A phone out of coverage for a day burned its retry budget on failed connections and parked a valid order as rejected. That is the loss a queue prevents.
A stale closure in a loop created six rows where one was intended, and an unordered query picked whichever of them the database felt like returning.
One dispatch per order was a scope decision. Removing it for partial shipments exposed a race where two dispatches could each ship the last unit.
A sale, a production run and an adjustment all wrote the same inventory row. One took a row lock, one wrote a ledger entry, and one did neither.
Offline delivery capture was a fiction, because the screen that records it could not be opened without a connection. The queue worked. Nothing could reach it.
Rows written in one transaction share an update time to the microsecond. A greater-than cursor drops them and a greater-or-equal cursor repeats them forever.
The same mistake bit a rental ledger three times in three months — a field naming an amount was read as proof the amount had moved.
A read followed by a check is not a guard. Two webhooks for one payment both passed it, and the customer's account was credited double the amount.
A customer paid a five thousand rupee deposit and was immediately asked for it again, because the ledger recorded the receipt as a new row.
Offline-first only works if the client can tell "already applied" apart from "rejected". A single conflict status collapses both into one answer.
A counter charge and an upstream re-price added the same 1,593 rupees an hour apart. Both stood, and the ledger held back the customer's deposit for it.
Designing field apps for staff with no signal: local-first writes, durable queues, idempotency and conflict rules decided by the business.