介面冪等性就是使用者對於同一操作發起的一次請求或者多次請求的結果是一致的,不會因為多次點選而產生了***。舉個最簡單的例子,那就是支付,使用者購買商品後支付,支付扣款成功,但是返回結果的時候網路異常,此時錢已經扣了,使用者再次點選按鈕,此時會進行第二次扣款,返回結果成功,使用者查詢餘額返發現多扣錢了,流水記錄也變成了兩條,這就沒***介面的冪等性
在增刪改查4個操作中,尤為注意就是增加或者修改,
查詢對於結果是不會有改變的,查詢一次和查詢多次,在資料不變的情況下,查詢結果是一樣的。select是天然的冪等操作
刪除一次和多次刪除都是把資料刪除。(注意可能返回結果不一樣,刪除的資料不存在,返回0,刪除的資料多條,返回結果多個,在不考慮返回結果的情況下,刪除操作也是具有冪等性的)
修改在大多場景下結果一樣,但是如果是增量修改是需要保證冪等性的,如下例子:
增加在重複提交的場景下會出現冪等性問題,如以上的支付問題
常見的兩種實現方案: 1. 通過**邏輯判斷實現 2. 使用token機制實現 下面以支付系統為例,分別對介面的冪等性進行說明與實現
使用者購買商品的訂單系統與支付系統;訂單系統負責記錄使用者的購買記錄已經訂單的流轉狀態(orderstatus),支付系統用於付款,提供如下介面,訂單系統與支付系統通過分布式網路互動。
這種情況下,支付系統已經扣款,但是訂單系統因為網路原因,沒有獲取到確切的結果,因此訂單系統需要重試。由上圖可見,支付系統並沒有做到介面的冪等性,訂單系統第一次呼叫和第二次呼叫,使用者分別被扣了兩次錢,不符合冪等性原則(同乙個訂單,無論是呼叫了多少次,使用者都只會扣款一次)。如果需要支援冪等性,付款介面需要修改為以下介面:
boolean pay(int orderid,int accountid,bigdecimal amount)
通過orderid來標定訂單的唯一性,付款系統只要檢測到訂單已經支付過,則第二次呼叫不會扣款而會直接返回結果:
在不同的業務中不同介面需要有不同的冪等性,特別是在分布式系統中,因為網路原因而未能得到確定的結果,往往需要支援介面冪等性。
隨著分布式系統及微服務的普及,因為網路原因而導致呼叫系統未能獲取到確切的結果從而導致重試,這就需要被呼叫系統具有冪等性。例如上文所闡述的支付系統,針對同乙個訂單保證支付的冪等性,一旦訂單的支付狀態確定之後,以後的操作都會返回相同的結果,對使用者的扣款也只會有一次。這種介面的冪等性,簡化到資料層面的操作:
update useramount set amount = amount - 'value' ,paystatus = 'paid' where orderid= 'orderid' and paystatus = 'unpay'
其中value是使用者要減少的訂單,paystatus代表支付狀態,paid代表已經支付,unpay代表未支付,orderid是訂單號。
在上文中提到的訂單系統,訂單具有自己的狀態(orderstatus),訂單狀態存在一定的流轉。訂單首先有提交(0),付款中(1),付款成功(2),付款失敗(3),簡化之後其流轉路徑如圖:
當orderstatus = 1 時,其前置狀態只能是0,也就是說將orderstatus由0->1 是需要冪等性的
update order set orderstatus = 1 where orderid = 'orderid' and orderstatus = 0
當orderstatus 處於0,1兩種狀態時,對訂單執行0->1 的狀態流轉操作應該是具有冪等性的。這時候需要在執行update操作之前檢測orderstatus是否已經=1,如果已經=1則直接返回true即可。
但是如果此時orderstatus = 2,再進行訂單狀態0->1 時操作就無法成功,但是冪等性是針對同乙個請求的,也就是針對同乙個requestid保持冪等。
這時候再執行
update order set orderstatus = 1 where orderid = 'orderid' and orderstatus = 0
介面會返回失敗,系統沒有產生修改,如果再發一次,requestid是相同的,對系統同樣沒有產生修改。
token機制實現步驟:
生成全域性唯一的token,token放到redis或jvm記憶體,token會在頁面跳轉時獲取.存放到pagescope中,支付請求提交先獲取token
提交後後台校驗token,執行提交邏輯,提交成功同時刪除token,生成新的token更新redis ,這樣當第一次提交後token更新了,頁面再次提交攜帶的token是已刪除的token後台驗證會失敗不讓提交
token特點: 要申請,一次有效性,可以限流
介面的冪等性
在微服務架構下,我們在完成乙個訂單流程時經常遇到下面的場景 乙個訂單建立介面,第一次呼叫超時了,然後呼叫方重試了一次 在訂單建立時,我們需要去扣減庫存,這時介面發生了超時,呼叫方重試了一次 當這筆訂單開始支付,在支付請求發出之後,在服務端發生了扣錢操作,介面響應超時了,呼叫方重試了一次 乙個訂單狀態...
介面的冪等性
乙個操作,無論執行多少次,產生的效果和返回的結果都是一樣的.查詢和刪除操作具有天然的冪等性,新增和修改需要保證冪等性.在redis中儲存token實現冪等性 當客戶端需要請求新增或修改介面時,需要先向伺服器請求token 伺服器接收到客戶端請求token的請求,生成token並儲存在redis中,然...
冪等性學習及介面的冪等性
冪等性學習 一 什麼是冪等性 在這裡需要有以下幾個問題需要注意 2 冪等性不僅僅只是一次或者多次請求的時候對資源沒有 比如根據id對資料庫的查詢操作,此操作對資料庫沒有增刪改,所以多次查詢操作對資料庫結果是沒有任何影響的 3 冪等性還包括了第一次請求資源的時候,對資源產生了 但是在以後多次同樣的請求...