幂等性 (Idempotent)

👀 5 min read 👀

大家好,我是 Cindy,關於幂等性 (Idempotent)我已經聽説過 3 次了,還記不住(事不過三?亂用成語),所以決定記錄下來,順便分享給大家,下面會是我的筆記,如果有錯歡迎大家留言跟我說唷!

什麼是冪等性?

冪等性最早是數學裡面的一個概念,後來被用於計算機領域,用於表示任意多次請求均與一次請求執行的結果相同,也就是說對於一個介面而言,無論呼叫了多少次,最終得到的結果都是一樣的。詳細可以參考 維基百科。

HTTP 的冪等性

  • GET: 安全(Safe)且 冪等(Idempotent),用來讀取數據
  • POST: 不安全(Non-safe) 且不是冪等(non-idempotent),用來新增數據或執行某個操作
  • PUT: 不安全(Non-safe) 但冪等(idempotent),用來置換數據
  • PATCH: 不安全(Non-safe) 且不是冪等(non-idempotent),用來修改數據
  • DELETE: 不安全(Non-safe) 但冪等(idempotent),用來刪除數據
  • 參考: HTTP Verbs: 談 POST, PUT 和 PATCH 的應用、HTTP 方法

從 RESTful 服務的角度來看,要使操作(或服務調用)具有冪等性,客戶端可以在產生相同結果的同時重複進行相同的調用。換句話說,發出多個相同的請求與發出單個請求具有相同的效果。請注意,雖然冪等操作在服務器上產生相同的結果(沒有副作用),但響應本身可能不同(例如,資源的狀態可能會在請求之間發生變化)。

PUT 和 DELETE 方法被定義為冪等的。但是,有一個關於 DELETE 的警告。DELETE 的問題,如果成功通常會返回 200(OK)或 204(No Content),在後續調用中通常會返回 404(Not Found),除非該服務被配置為“標記”要刪除的資源而不實際刪除它們。但是,當服務實際刪除資源時,下一次調用將找不到資源將其刪除並返回 404。但是,每次 DELETE 調用後服務器上的狀態都是一樣的,只是響應不同。

為什麼 PATCH 是 non-idempotent

A PATCH is not necessarily idempotent, although it can be. Contrast this with PUT; which is always idempotent. The word “idempotent” means that any number of repeated, identical requests will leave the resource in the same state. For example if an auto-incrementing counter field is an integral part of the resource, then a PUT will naturally overwrite it (since it overwrites everything), but not necessarily so for PATCH.

從 MDN Web Docs 的說明可以知道 PATCH 可以是 idempotent,但不一定是,像是自動增加數值的欄位更新。

如何保證介面的冪等性?

前端攔截 (但可能被跳過)

disable 按鈕

前端這邊我沒有詳細察,所以只列了這個QQ

使用資料庫實現冪等性

  1. 唯一索引,防止新增髒資料
  2. 悲觀鎖
    db lock
  3. 樂觀鎖
    用 version 控制
    先 select 拿到版號,做完更新版號+1
    如果版號不是差 1 就不動做
  4. Atomic Transactions
  5. select insert
    併發不高的後臺系統,或者一些任務 JOB,為了支援冪等,支援重複執行,簡單的處理方法是,先查詢下一些關鍵資料,判斷是否已經執行過,在進行業務處理,就可以了。
    注意:核心高併發流程不要用這種方法。

使用分散式鎖實現冪等性

如果是分佈式系統,構建全域性唯一索引比較困難,例如唯一性的欄位沒法確定,這時候可以引入分散式鎖,通過第三方的系統(redis 或 zookeeper),在業務系統插入資料或者更新資料,獲取分散式鎖,然後做操作,之後釋放鎖,這樣其實是把多執行緒併發的鎖的思路,引入多個系統,也就是分散式系統中的解決思路。

token 機制

參考 - 流程圖
這裡要結合業務考慮這種場景:如果請求處理失敗,前端是否需要重新申請 token 進行重試(因為此時 token 在服務端已經被刪除)。
tip: 先刪除 token 再進行業務操作

狀態機

在設計單據相關的業務,或者是任務相關的業務,肯定會涉及到狀態機(狀態變更圖),就是業務單據上面有個狀態,狀態在不同的情況下會發生變更,一般情況下存在有限狀態機,這時候,如果狀態機已經處於下一個狀態,這時候來了一個上一個狀態的變更,理論上是不能夠變更的,這樣的話,保證了有限狀態機的冪等。

結論

幂等性其實就是想辦法確保最終一致性,可以當成一種概念,用在我們設計程式的時候,思考的一個方向,像是這個業務邏輯是否有需要確保最終一致性,是否會有重複執行的可能性,重複執行的時候要視為成功或失敗,如何避免重複執行造成的錯誤,都是我們要思考的地方。


其他參考資料: