How does optimistic locking with a version column work?
Optimistic locking is a concurrency control strategy that avoids holding database locks during reads. Instead of locking a row when you read it, you record its current version, perform your computation, and then verify the version hasn't changed at write time. If another transaction modified the row between your read and your write, the version check fails and your update is rejected — you then retry with fresh data.
The implementation adds a `version` column (integer or timestamp) to the table. The pattern is:
1. Read: `SELECT id, balance, version FROM accounts WHERE id = 42` — returns version = 7. 2. Process: compute the new balance in application code. 3. Write: `UPDATE accounts SET balance = 950, version = 8 WHERE id = 42 AND version = 7`. 4. Check rows affected: if 0 rows updated, a concurrent modification occurred — retry from step 1.
The `WHERE version = 7` clause is the guard. If another transaction incremented the version to 8 before your update, your WHERE clause matches 0 rows, the update silently does nothing, and your application detects the conflict via `affected rows = 0`.
Optimistic locking is well-suited for low-contention scenarios where conflicts are rare. The read path has no overhead — no locks held, no blocking. Under high contention, retry storms can develop: many concurrent writers all reading the same version, all but one failing, all retrying — creating thundering herd behavior that can be worse than pessimistic locking.
ORMs like Hibernate and JPA support optimistic locking natively via `@Version` annotations. The framework handles version increment and conflict detection automatically, throwing `OptimisticLockException` on conflict.
Timestamp-based versions (using `updated_at`) are less reliable than integer counters because two updates within the same millisecond can produce identical timestamps, creating a false sense of no conflict.
Explains the version column pattern with the correct UPDATE WHERE version = N statement, and knows to check affected rows to detect conflicts.
Compares to pessimistic locking (no locks during read = better read scalability), explains the retry mechanism, identifies high-contention retry storms as a failure mode, and mentions timestamp vs integer version trade-offs.
Reading the answer is step one. Explaining it unprompted — under interview pressure — is what actually matters. Get AI-graded feedback on your answer with follow-up probes on your weak points.
Get Graded — Free Assessment