今天看到一篇講冪等的文章,想起來上次面試的時候有問過,記錄一下,加深印象。
首先說一下冪等的概念,官方一點的說法是:在程式設計中乙個冪等操作的特點是其任意多次執行所產生的影響均與一次執行的影響相同。其實可以簡單理解為多次操作和一次操作的結果是一樣的。
一般情況下介面正常呼叫的時候返回資訊不會重複提交,但某些情況可能會導致重複提交。比如:
1:前端重複提交表單:在填寫一些**時候,使用者填寫完成提交,很多時候會因網路波動沒有及時對使用者做出提交成功響應,致使使用者認為沒有成功提交,然後一直點提交按鈕,這時就會發生重複提交表單請求。
2、使用者惡意進行刷單:例如在實現使用者投票這種功能時,如果使用者針對乙個使用者進行重複提交投票,這樣會導致介面接收到使用者重複提交的投票資訊,這樣會使投票結果與事實嚴重不符。3、介面超時重複提交:很多時候 http 客戶端工具都預設開啟超時重試的機制,尤其是第三方呼叫介面時候,為了防止網路波動超時等造成的請求失敗,都會新增重試機制,導致乙個請求提交多次。
4、訊息進行重複消費:當使用 mq 訊息中介軟體時候,如果發生訊息中介軟體出現錯誤未及時提交消費資訊,導致發生重複消費。
引入冪等也是會對系統有影響的,比如:1、把並行執行的功能改為序列執行,降低了執行效率。2、增加了額外控制冪等的業務邏輯,複雜化了業務功能;所以在引入冪等性之前,我們要考慮清楚看是否有必要引入。
那麼下面就介紹一些實現冪等的幾種方案:
1、查詢操作:查詢一次和查詢多次,在資料不變的情況下,查詢結果是一樣的。select是天然的冪等操作;同理刪除操作也是冪等的
2、唯一索引:比如說賬戶,怎麼能保證每個人只能有乙個賬戶,給資金賬戶表裡的使用者id新增唯一索引就ok。
3、token:防止頁面重複提交。通過session token實現,客戶端請求頁面時,伺服器會生成乙個隨機數token,將token放置到session中,然後將token發給客戶端。下次客戶端提交請求時,token會隨著表單一起提交到伺服器端。伺服器端第一次驗證相同過後,會將session中的token值更新下,若使用者重複提交,第二次的驗證判斷將失敗,因為使用者提交的表單中的token沒變,但伺服器端session中token已經改變了。
4、悲觀鎖:獲取資料的時候加鎖獲取,悲觀鎖使用時一般伴隨事務一起使用。
5、樂觀鎖:樂觀鎖只是在更新資料那一刻鎖表,其他時間不鎖表。相對於悲觀鎖效率更高。樂觀鎖的實現方式很多,比如通過version或其他狀態條件。
6、分布式鎖:分布式系統的話可以選擇引入第三方來實現,比如redis,zk等。這部分是內容比較多,簡單來說就是在業務系統插入資料或者更新資料,獲取分布式鎖,然後做操作,之後釋放鎖。
7、狀態機:狀態機的應用是比較多的,其實有表單就可以考慮做狀態機,根據狀態去流轉。
冪等是比較常用的乙個操作,尤其是跟資金相關的業務上非常常見,也是比較重要的乙個問題,冪等做不好會出現很多問題,比如重複支付等,會很麻煩使用者體驗也不好,所以學習一下蠻重要的。
冪等性解決方案
1 token方案,前端請求時服務端生成乙個token給前端,在這個請求沒處理完時這個token永遠生效,在這個過程中如果前端重複請求,服務端判斷這個token,如果發現是同乙個則不予理睬,請求處理完畢後釋放token 2 利用mysql行鎖 前端進入某個頁面自己生成乙個唯一標識,給服務端傳過來,服...
什麼是冪等性?
http 冪等方法,是指無論呼叫多少次都不會有不同結果的 http 方法。不管你呼叫一次,還是呼叫一百次,一千次,結果都是相同的。http get 方法,用於獲取資源,不管呼叫多少次介面,結果都不會改變,所以是冪等的。get tickets 獲取ticket列表 get tickets 12 檢視某...
保證介面冪等性的解決方案(後台)
假如有個服務提供乙個介面 服務部署在多個服務機器 接著有個介面是付款介面。使用者在前端上操作的時候,乙個訂單不小心發起了兩次支付請求,然後這兩個請求分散在了這個服務部署的不同的機器上,結果乙個訂單扣款扣兩次。這樣的場景,就是介面沒 冪等性的結果。保證冪等性的核心 1.對於每個請求必須有乙個唯一的標識...