20200117 實現介面冪等的幾種方式

2021-10-02 06:09:43 字數 1699 閱讀 1851

實現介面冪等性,防止併發操作,如何設計介面冪等方案?

當前是否有高併發的場景,如果是才需要處理介面冪等操作,如果不是就不需要處理。

插入更改操作,都要考慮高併發條件下的冪等性。

介面的冪等性實際上就是介面可重複呼叫,在呼叫方多次呼叫的情況下,介面最終得到的結果是一致的。

在高併發條件下,如果每秒200個執行緒註冊,有可能num=-2, 驗證成功,導致資料落庫,所以應該是<= -1

1、redis:setnx實現分布式鎖,防止多個相同操作同時執行。

2、mysql:select......for update (悲觀鎖) ,配合spring事務一起使用,可以防止更新丟失。

3、前後端互動:前端呼叫介面時,先從後端獲取乙個令牌;請求介面時,後端直接刪除當前令牌,如果刪除成功,繼續執行;如果刪除失敗,返回正在處理中。

4、mysql:使用資料庫的唯一索引機制,比如對訂單號建立唯一索引,防止訂單號的重複。

5、mysql:通過資料庫版本號實現冪等操作,通過mysql實現樂觀鎖(更新操作)。

6、redis分布式鎖:在業務系統插入資料或者更新資料,獲取分布式鎖,然後做操作,之後釋放鎖,這樣其實是把多執行緒併發的鎖的思路(redis的實現有多種方式,原子操作,遞增,遞減)

7、mysql聯合唯一索引:乙個特定的業務場景,三個字段肯定確定唯一性,那麼,可以在資料庫表新增唯一索引來進行標示。

8、有限狀態機冪等,通過某種指定狀態才能更新成下個狀態。

9、類似double check機制的確認機制

悲觀鎖和樂觀鎖大部分場景下差異不大,一些獨特場景下有一些差別,一般我們可以從如下幾個方面來判斷:

1)響應速度:如果需要非常高的響應速度,建議採用樂觀鎖方案,成功就執行,不成功就失敗,不需要等待其他併發去釋放鎖

2)衝突頻率:如果衝突頻率非常高,建議採用悲觀鎖,保證成功率,如果衝突頻率大,樂觀鎖會需要多次重試才能成功,代價比較大

3)重試代價:如果重試代價大,建議採用悲觀鎖。

3、redis分布式鎖,支付完刪除值,所以可以防止多次提交。

setnx key value

將ke的值設為value,當且僅當key不存在。若給定的key已經存在,則setnx 不做任何動作。

返回值:設定成功,返回1。設定失敗,返回0。

setnx 是『set if not exists』(如果不存在,則 set)的簡寫。

行鎖,排它鎖:

for update是在資料庫中上鎖用的,可以為資料庫中的行上乙個排它鎖。當乙個事務的操作未完成時候,其他事務可以讀取但是不能寫入或更新。

如果查詢不到,鎖失效? 如果查詢不到,同時進行插入操作,還是會插入多條重複的記錄。

但是請注意如果查詢範圍比較大有可能會鎖住整張表,確定主鍵索引才能使用

注意:當選中某乙個行的時候,如果是通過主鍵id選中的,那麼這個時候是行級鎖。 

其他行還是可以直接insert 或者update的。如果是通過其他的方式選中行,或者選中的條件不明確包含主鍵,這個時候會鎖表。其他的事務對該錶的任意一行記錄都無法進行插入或者更新操作,只能讀取。

鎖定一行還是鎖定多行,還是鎖表? 這個盡量別使用,如果鎖表將會導致整個專案效能低下。

刪除操作:設定過期時間為2分鐘,兩分鐘內還沒請求,令牌自動失效。

冪等操作校驗,可以通過註解來實現麼? 完全可以封裝乙個註解。

Mysql實現冪等 基於資料庫實現冪等介面

tl dr 通過唯一編號確定同一請求,沒有唯一編號的自行生成。資料庫記錄操作狀態,資料庫事務保證資料一致性。概述通過http api進行通訊的系統,在支付或者只允許操作一次的相關場景中,對介面的冪等性有嚴格要求。介面的冪等性體現在 請求執行成功所得到的結果與次數無關 如果介面沒有實現冪等性,對於轉賬...

介面冪等設計

在系統設計時,經常會出現每次操作結果都需要一致的場景。比如典型的restful get請求 每次請求url student 1 查詢第乙個學生 結果都是一樣的。當然排除再修改學生資訊後又查詢的情況。介面冪等,通俗的定義可以為 每次同樣的請求操作該介面,得到的結果都是一樣的。先給個場景,同樣的訂單編號...

介面冪等性

例如 在http協議中,get請求,會得到同樣的資料 bool get money id,amount 1引數 id 使用者的賬戶 amount 表示取多少錢 返回值 true 表示取錢成功 false 表示取錢失敗 情景一 1 一位使用者a 取100塊錢,這個請求,傳送到了伺服器 2 伺服器正常的...