Skip to content

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.

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.

A holds the lock; B waits before reading.
Editor AEditor BStored version
Step 1Read v1Hold lockArrivesMust waitv1
Step 2Prepare editWaitingv1
Step 3Commit v2Release lockWaitingv2
Step 4DoneRead v2Then commit v3v3
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.

Both work; a stale commit is rejected.
Editor AEditor BStored version
Step 1Read v1Read v1v1
Step 2Prepare editCommit v2v2
Step 3Reject v1Expected version staleDonev2
Step 4Reload v2Retry commits v3Donev3
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

Prime · Source of the tension

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.

Read the source section

Compare-and-Swap or Version Guard

Mechanism · Related concept

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.

Read the source section

When it helps, and when it misleads

Under high contention the retries pile up and throughput can collapse below what a lock would give.

Read the source section

Atomic Check-and-Use Operation

Mechanism · Related concept

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.

Read the source section