幂等性 (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,為了支援冪等,支援重複執行,簡單的處理方法是,先查詢下一些關鍵資料,判斷是否已經執行過,在進行業務處理,就可以了。
    注意:核心高併發流程不要用這種方法。

使用分散式鎖實現冪等性

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

token 機制

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

狀態機

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

結論

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


其他參考資料: