2012-08-06 76 views
1

我試圖設計一個REST風格的Web API,所以我一直在研究rfc2616。我喜歡使用ETags進行樂觀併發的想法,並試圖使用它來創建一種安全的方式來添加資源,而無需競爭條件。不過,我注意到以下兩個語句在section 14.24if-match HTTP標頭是否需要兩階段提交?

如果請求將,而如果-Match頭場,導致比一個2xx或412狀態的其它任何東西,那麼如果-Match頭必須被忽略。

意圖更新資源(例如,PUT)的請求可以包括If-Match頭字段以表示如果對應於If-Match值的實體(單個實體標籤)不再是該資源的表示。

我正在使用RDBMS,不知道事務是否會成功提交,直到我嘗試它,所以我認爲第一個需求似乎有點繁重。考慮有人提供一個If-Match標頭與ETags不匹配的情況:如果提交會成功,那麼我應該聽取If-Match標題,不要嘗試提交,並返回412.如果提交失敗,那麼沒有If-Match標頭的請求將會導致一個非2XX/412響應,所以我必須忽略If-Match標題,這意味着我應該嘗試提交。

至於我能弄清楚,我有兩個選擇:

  1. 使用2階段提交獲得遠見到是否提交嘗試之前一定會成功。
  2. 忽略上面的第一個要求,並且返回412,即使忽略If-Match會導致非2XX/412響應。 (這是我傾向的那個)

還有其他想法嗎?我誤解了規格嗎?

+0

略有關,可能是爲412人羣的興趣:http://stackoverflow.com/questions/3620203/http- status-412-precondition-failed-and-database-versioning?rq = 1 – Thilo 2012-08-06 01:13:41

回答

3

會不會像「更新,除非修改」(樂觀鎖定)的工作?該實體需要在數據庫中存儲版本號或etag。

  1. 運行驗證,不需要提交,忽略的eTag,返回錯誤,如果有必要

  2. 更新實體其中id =:the_id和ETag =:expected_etag

  3. 這要麼返回0或1的受影響的行

  4. 如果0資源已經看到併發更新(或ID是完全錯誤,您可以單獨檢查)。在這種情況下返回412

  5. 提交

  6. 如果提交失敗,返回錯誤酌情

+0

謝謝,我沒有考慮將其推入數據庫。 – 2012-08-06 01:53:08

0

這也許是有些在理論方面,但基於我目前的HTTP的理解規範,我會分類使用If-Match-like頭幾乎不能用於所有,但可能安全的方法,因爲這樣:

「如果需要如果沒有If-Match頭字段,est會產生2xx或412狀態以外的任何內容,那麼If-Match頭必須被忽略。

爲什麼?僅僅因爲在大多數實際情況下,預測如果請求被執行會發生什麼是不可能的。

作爲一個例子,誰可以預見IO級錯誤或者必須運行的代碼中發生的一些特殊情況?

它會更「可解」如果5XX其中加入到2XX和412