Optimistic Concurrency Control
Optimistic concurrency control runs transactions without locks and validates versions at commit, retrying on conflict. It scales under low contention but degrades when many writers contend for the same rows.
Optimistic concurrency control (OCC) assumes that conflicting concurrent updates are uncommon, so it lets transactions run without holding locks and only checks for conflicts when they try to commit. If the data a transaction read has changed underneath it, the commit is rejected and the transaction retries. By avoiding locks on the read and compute phases, OCC scales well under low contention.
How It Works
Each record carries a version marker — a version number, timestamp, or row hash. A transaction reads the record and its version, does its work, and at commit issues a conditional update: "set these values if the version is still what I read." If the version matches, the update succeeds and the version increments; if it does not, another writer won the race, the update affects zero rows, and the application detects the conflict and retries (or surfaces it to the user). ORMs implement this with a @Version column (JPA/Hibernate, Entity Framework's concurrency token); NoSQL stores expose conditional writes (DynamoDB condition expressions, ETags, compare-and-swap). The check and write must be atomic.
When to Use It
Use OCC when contention on the same rows is low, transactions are short, and you want high read and write throughput without lock overhead: typical web CRUD, REST APIs with ETag-based concurrency, and distributed stores that lack or discourage long-held locks. It also avoids the deadlocks that pessimistic locking can cause.
Trade-offs
Under high contention OCC degrades: many transactions reach commit only to be rejected and retried, wasting the work they did and potentially live-locking. It pushes conflict handling into the application, which must implement retry logic and present conflicts sensibly. It is poorly suited to long transactions touching hot rows. When contention is high or critical sections long, pessimistic locking is usually better.
Related Patterns
OCC is the counterpart to pessimistic-locking, complements distributed-commit protocols like two-phase-commit, and pairs with the idempotent-writer pattern so that commit retries remain safe.
Example
A document editor saves changes with an ETag returned when the document was loaded. On save, the client sends If-Match: <etag>. If another user saved first, the version no longer matches, the server returns 412 Precondition Failed, and the client reloads, re-applies the edit, and retries — all without ever holding a lock on the document.