Tensions in Practice: Acquisition flexibility in tension with deadlock prevention¶
Concurrent work · two needed resources
One worker holds resource A and needs B; another holds B and needs A. Both can wait forever even though neither resource is broken. A shared acquisition order prevents that circle from forming. A system can instead permit flexible acquisition, detect a circle, and abort some work to break it. Ordinary waiting remains possible under either arrangement.
Allow flexible acquisition
Let work request resources as its needs emerge.
Avoid a frozen wait cycle
Keep circular resource dependencies from indefinitely blocking every participant.
Why these aims pull against each other
A universal order restricts acquisition before a cycle occurs. Detection and recovery retain flexibility but require an actual interruption after a cycle is found.
Choose an arrangement to see what changes and what remains difficult.
Qualitative paths and conditions, not measured costs, timings or performance guarantees.
What this choice protects
What it costs
When it fits
Compare the arrangements
One acquisition order
All relevant code acquires A before B, releasing and reacquiring if it discovers a lower-ranked need.
- What it protects
- The illustrated opposite-order cycle cannot form when every participant obeys the ordering rule.
- What it costs
- The rule constrains code and can require release/reacquisition or less convenient resource use.
- When it fits
- A consistent order can be agreed and enforced across every relevant acquisition path.
Illustration note: The schematic concerns this class of resource-lock deadlock only. It does not promise fairness, bounded waiting, or freedom from other dependency cycles.
Detect and recover
Use flexible acquisition and detect a wait cycle; abort a selected participant and release its resources.
- What it protects
- Work is not constrained to the same static acquisition sequence.
- What it costs
- Detection costs time and coordination; aborted work is lost and retries can create further conflicts.
- When it fits
- Operations can be safely rolled back, cycles can be detected, and the recovery policy can tolerate aborts.
Illustration note: The detector is represented by a labeled recovery edge, not a full distributed detection algorithm. The sketch does not guarantee eventual retry success.
What this illustration does—and does not—establish
Deadlock: Guaranteed Prevention vs Adaptive Recovery supplies prevention versus recovery. The lock-order mechanism supplies the precise universal acquisition rule and its scope.
- A process simply waiting for a holder that can finish is not deadlocked.
- A timeout alone does not prove a cycle exists.
- Preventing cycles does not prevent starvation or every form of failure.
Source entries
Deadlock
Deadlock: Guaranteed Prevention vs Adaptive Recovery supplies the conflict examined here.
Guaranteed Prevention vs Adaptive Recovery
- T4: Guaranteed Prevention vs Adaptive Recovery. Some systems prevent deadlock statically (lock ordering, bankers' algorithm) with a proof that deadlock is impossible. Others detect and recover dynamically (timeouts, abort-and-retry). Prevention trades flexibility for certainty; recovery retains flexibility but risks cascade failures if deadlock detection is slow or expensive (many transactions abort, retry, and deadlock again). A common failure is mixing prevention and recovery strategies without clear boundaries, leading to unpredictable failure modes.
Lock Ordering Protocol
Defines and bounds the increasing-order protocol shown in the prevention arrangement.
How it works
- Acquire strictly upward. A thread may request a lock only if its rank exceeds every lock the thread currently holds; needing a lower-ranked lock means releasing and re-acquiring in order. Because all edges now point up the ranking, the wait-for graph is provably acyclic.
When it helps, and when it misleads
Its failure mode is that the guarantee is only as strong as its *universality*: one code path, one library, one careless thread that acquires out of order reintroduces the cycle, and these violations are exactly the intermittent, load-dependent bugs that are hardest to catch in testing — the classic misuse is a partial rollout where "most" code follows the order and the rare violator deadlocks in production. It also does not help when the set of needed locks is not known until mid-transaction, or when a total order simply cannot be agreed across independently-developed components. The guarding discipline is to make the order machine-enforced rather than merely documented, so a violation fails loudly at the point of the offending acquisition instead of silently at some future interleaving.