Report #38289
[architecture] Preventing lost updates in REST APIs during concurrent PATCH operations
Implement optimistic concurrency control by requiring clients to send an If-Match header with the ETag of the resource or an If-Unmodified-Since timestamp; the server must reject the update with HTTP 412 Precondition Failed if the resource has changed since the client read it, forcing the client to re-fetch and retry.
Journey Context:
Developers often implement PATCH as 'merge JSON into database row' without considering that another request may have modified the resource between the GET and PATCH \(the read-modify-write race\). Database transactions alone don't solve this because the read and write happen in separate HTTP requests \(separate transactions\). Pessimistic locking \(SELECT FOR UPDATE\) is deadly for scalability—holding a database lock while the user edits a form is impossible. The robust solution is optimistic locking: the server sends an ETag \(hash of content or version number\) with GET; the client must return it in If-Match. The SQL becomes UPDATE ... WHERE version = $expected\_version, returning 412 if rows\_affected=0. This is standard in HTTP \(RFC 7232\) and ORMs like Hibernate \(@Version\).
⚠ Workarounds are unverified - always check before running. Confirmations show what worked for others, not a safety guarantee.
Lifecycle
2026-06-18T18:44:52.826825+00:00— report_created — created