Tensions in Practice: Uninterrupted preparation in tension with concurrent progress¶
Shared record · two editors and a monotonic version
Two editors prepare changes to one record. Holding a lock while A reads and prepares makes B wait, preserving the state A relies on. Letting both prepare concurrently avoids that initial wait, but A’s expected version can become stale when B commits first. An atomic version guard rejects A’s stale commit; it does not make A’s earlier work disappear for free.
Preserve prepared work against interference
Avoid discovering at commit that the state used for preparation has changed.
Let independent preparation proceed
Avoid holding other writers out during work that may not conflict.
Why these aims pull against each other
The two arrangements put the coordination cost at different points: waiting before protected preparation, or rejecting and repeating work when an optimistic commit discovers a changed version.
Choose an arrangement to see what changes and what remains difficult.
Finite illustrative comparisons. Labels carry the meaning; color does not establish a preference or measured effect.
What this choice protects
What it costs
When it fits
Compare the arrangements
Hold through preparation
A holds a correctly enforced lock across reading, preparation and commit, then B reads the updated record. The four steps are one illustrative execution, not equal time slices.
| Editor A | Editor B | Stored version | |
|---|---|---|---|
| Step 1 | Read v1Hold lock | ArrivesMust wait | v1 |
| Step 2 | Prepare edit | Waiting | v1 |
| Step 3 | Commit v2Release lock | Waiting | v2 |
| Step 4 | Done | Read v2Then commit v3 | v3 |
- What it protects
- A’s preparation is not invalidated by B during the protected interval.
- What it costs
- B waits for the whole interval, including A’s preparation; slow work or a stranded lock extends that dependency.
- When it fits
- Fits expensive retries or frequent interference when the protected interval remains short and correctly managed.
Illustration note: Only this one record and participating writers are covered. No external action or earlier authorization is silently included in the lock.
Check the version at commit
Both read version v1. B commits v2 before A. A’s atomic expected-version test rejects; A then reloads and reapplies its edit to v2. The final retry is stipulated to have no further intervening writer.
| Editor A | Editor B | Stored version | |
|---|---|---|---|
| Step 1 | Read v1 | Read v1 | v1 |
| Step 2 | Prepare edit | Commit v2 | v2 |
| Step 3 | Reject v1Expected version stale | Done | v2 |
| Step 4 | Reload v2Retry commits v3 | Done | v3 |
- What it protects
- B can commit without waiting for A’s full preparation.
- What it costs
- A must inspect fresh state and redo or reconcile its edit; repeated interference can cause repeated retries.
- When it fits
- Fits infrequent conflicts, affordable retries and a correct atomic compare-and-write with nonreused monotonic version tokens.
Illustration note: The version guard’s compare and write are themselves atomic. Optimism does not mean a separate unprotected check followed by a write.
What this illustration does—and does not—establish
The prime supplies temporal binding cost. The two related mechanisms supply protected versus optimistic execution; the table exposes waiting versus discarded preparation without claiming one eliminates coordination.
- A successful retry must reapply intent to fresh state rather than blindly overwrite B’s update.
- Tokens must distinguish relevant changes; a reused bare value can miss a change away and back.
- The table shows one finite schedule and supplies no fairness, latency or eventual-success guarantee.
Source entries
Time-Of-Check To Time-Of-Use Flaw
Time-Of-Check To Time-Of-Use Flaw: Binding Strength versus Coordination Cost (coupling) supplies the conflict examined here.
Binding Strength versus Coordination Cost (coupling)
The binding-strength continuum trades exposure against cost — atomic re-check is strongest but costs latency and coordination, while check-once is cheapest but maximally exposed.
Compare-and-Swap or Version Guard
Supplies atomic version comparison, explicit rejection and retry cost.
How it works
- Swap only on match. The store applies the change *only if* current equals expected, and bumps the version on success — done as one atomic compare-and-set so the compare and the write cannot themselves be split. - Reject and retry on mismatch. A differing marker means the referent moved; the operation fails and is retried against the fresh state rather than forcing a stale write through.
When it helps, and when it misleads
Under high contention the retries pile up and throughput can collapse below what a lock would give.
Atomic Check-and-Use Operation
Supplies the protected boundary and the cost of holding it across work.
When it helps, and when it misleads
Its costs are the price of exclusivity. A wide boundary serializes work and throttles the system; a held lock that outlives its holder stalls everyone behind it; and it protects *only* what is inside the boundary — anything the action depends on outside it is still racy.