## 并發控制
不嚴謹的實現,或者缺少并發控制的?`PUT`?和?`PATCH`?請求可能導致 “更新丟失”。這個時候可以使用`Last-Modified`?和/或?`ETag`?頭來實現條件請求,支持樂觀并發控制。
下文只考慮使用?`PUT`?和?`PATCH`?方法更新資源的情況。
* 客戶端發起的請求如果沒有包含?`If-Unmodified-Since`?或者?`If-Match`?頭,那就返回狀態碼?`403 Forbidden`?,在響應正文中解釋為何返回該狀態碼
* 客戶端發起的請求提供的?`If-Unmodified-Since`?或者?`If-Match`?頭與服務器記錄的實際修改時間或?`ETag`?值不匹配的時候,返回狀態碼?`412 Precondition Failed`
* 客戶端發起的請求提供的?`If-Unmodified-Since`?或者?`If-Match`?頭與服務器記錄的實際修改時間或?`ETag`?的歷史值匹配,但資源已經被修改過的時候,返回狀態碼?`409 Conflict`
* 客戶端發起的請求提供的條件符合實際值,那就更新資源,響應?`200 OK`?或者?`204 No Content`?,并且包含更新過的?`Last-Modified`?和/或?`ETag`?頭,同時包含?`Content-Location`?頭,其值為更新后的資源 URI
相關資料:
* 《RESTful Web Services Cookbook 中文版》 10.4 節 《如何在服務器端實現條件 PUT 請求》
* [RFC 7232 "Conditional Requests"](https://tools.ietf.org/html/rfc7232)
* [Location vs. Content-Location](https://www.subbu.org/blog/2008/10/location-vs-content-location)