Implementing Concurrency Control
1. Using Optimistic Locking
Assume conflicts are rare; detect at write time using version/ETag.
| Mechanism | How |
| HTTP ETag | If-Match header check |
| Version field | WHERE version = ? AND id = ? |
| Timestamp | Last-Modified / If-Unmodified-Since |
| Result | Status |
| ETag matches → apply mutation | 200/204 |
| ETag mismatch → reject | 412 Precondition Failed |
| Header missing | 428 Precondition Required (optional) |
| Behavior | Result |
| Resource unchanged since date → apply | 200/204 |
| Modified after date → reject | 412 Precondition Failed |
4. Handling Concurrent Update Conflicts
| Resolution | UX |
| Last-write-wins | Silent overwrite (rarely correct) |
| Reject + 409/412 | Client refetches and retries |
| Three-way merge | Diff + auto-merge non-conflicting fields |
| CRDT | Conflict-free auto-merge |
5. Implementing Version Numbers
Example: Version-Based Update
UPDATE users
SET name = ?, version = version + 1, updated_at = NOW()
WHERE id = ? AND version = ?;
-- If 0 rows affected → conflict
6. Using Last-Modified Timestamps
| Pros | Cons |
| Human-readable | 1-second granularity insufficient for fast updates |
| Built-in HTTP support | Clock skew issues across servers |
7. Implementing Pessimistic Locking
| Mechanism | Use Case |
SQL SELECT FOR UPDATE | Hold DB row lock during transaction |
| Distributed lock (Redis, ZooKeeper) | Multi-instance critical section |
| Lease tokens | Time-limited exclusive access |
Warning: Avoid for HTTP APIs — they're stateless. Pessimistic locks block other writers; risk deadlocks.
8. Handling Lock Expiration
| Strategy | Implementation |
| TTL on lock | Auto-release after N seconds |
| Heartbeat extension | Client renews lock periodically |
| Owner verification | Token check on release |
9. Providing Conflict Resolution Strategies
Example: Conflict Response with Diff
{
"type": "https://example.com/errors/conflict",
"title": "Update Conflict",
"status": 409,
"currentVersion": "v5",
"yourVersion": "v3",
"currentResource": {...},
"diff": [
{"field": "email", "yours": "a@x.com", "theirs": "b@x.com"}
]
}
10. Documenting Concurrency Behavior
| Documentation | Content |
| Concurrency model | Optimistic vs pessimistic |
| Required headers | If-Match for mutations |
| Conflict format | Error response shape |
| Retry guidance | Refetch + retry strategy |