Learn the vocabulary of assuming no conflict, then verifying a version number before writing.
0 / 5 completed
1 / 5
At standup, a dev mentions a database update that reads a row's current version number, later writes back only if that version number hasn't changed in the meantime, and simply retries if it has. What is this concurrency-control strategy called?
Optimistic locking reads a row's current version number, does its work assuming no conflict will occur, and only checks at write time whether that version number still matches, writing successfully if it does and simply retrying if some other transaction changed it in the meantime. Pessimistic locking instead takes an actual lock on the row up front for the whole transaction, blocking any other transaction from touching it until the lock is released. This assume-no-conflict-then-verify approach is exactly what "optimistic" refers to, betting that conflicts will be rare enough that checking at the end is cheaper than blocking upfront.
2 / 5
During a design review, the team picks optimistic locking specifically for a workload where conflicting concurrent updates to the same row are expected to be rare. Which capability does this choice provide?
Choosing optimistic locking for a low-conflict workload provides higher throughput under low contention, since transactions never block waiting on a lock at all, and the only cost paid is an occasional retry on the rare occasion two transactions genuinely do conflict over the same row. Pessimistic locking instead makes every transaction touching that row wait for a lock regardless of whether a real conflict was ever actually going to occur, which adds unnecessary blocking overhead when conflicts are genuinely rare. This is exactly why the choice between optimistic and pessimistic locking depends heavily on how often real conflicts are actually expected for the specific workload.
3 / 5
In a code review, a dev notices an optimistic-locking update checks the row's version number at write time but has no retry logic at all when that check fails, simply discarding the user's change silently. What does this represent?
This is a missing retry path, since optimistic locking's entire design assumes a version-mismatch failure at write time will trigger either a retry, re-reading the row and reapplying the change, or at minimum surfacing the conflict back to the caller, rather than silently discarding the user's intended update as if it had never happened. A cache eviction policy is an unrelated concept about discarded cache entries. This silent-discard gap is exactly the kind of bug a reviewer needs to catch, since it means a user's change can vanish without any error or feedback at all whenever a genuine conflict occurs.
4 / 5
An incident report shows users occasionally reported their edits silently disappearing, and the root cause was traced to an optimistic-locking update whose version-mismatch failure path simply discarded the change instead of retrying or surfacing an error. What practice would prevent this?
Adding an explicit retry-or-surface-conflict path for the version-mismatch case ensures a real conflict either automatically retries the update against the row's fresh version, or at minimum clearly reports the failure back to the user instead of vanishing silently, which is exactly the fix for the disappearing edits described in this incident. Continuing to silently discard the change on a version mismatch is exactly what caused users to lose work without any indication anything had gone wrong. This explicit conflict-handling path is a required part of any correct optimistic-locking implementation, not an optional extra.
5 / 5
During a PR review, a teammate asks why the team chooses optimistic locking for this workload instead of just always taking a pessimistic lock up front to guarantee no conflict can ever occur in the first place. What is the reasoning?
Always taking a pessimistic lock up front forces every single transaction touching that row to wait for the lock, even in the vast majority of cases where no other transaction was actually going to conflict with it, which adds real blocking overhead and reduces throughput unnecessarily. Optimistic locking instead lets every transaction proceed without ever blocking, paying a retry cost only on the rare occasion a genuine conflict is detected at write time via the version-number mismatch. The tradeoff is that optimistic locking becomes wasteful, with transactions retrying over and over, if conflicts turn out to be far more common than expected, which is exactly why pessimistic locking is chosen instead for a workload where contention on the same row is known to be high.