成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

聊聊冪等性如何保證的

運維 數據庫運維
冪等概念來自數學,表示對數據源做N次變換和1次變換的結果是相同的。在工程中冪等性用來表示用戶對于同一操作發起的一次請求或者多次請求的結果是一致的,不會因為多次點擊而產生了副作用。

[[393173]]

 1 冪等性

1.1 定義

冪等概念來自數學,表示對數據源做N次變換和1次變換的結果是相同的。在工程中冪等性用來表示用戶對于同一操作發起的一次請求或者多次請求的結果是一致的,不會因為多次點擊而產生了副作用。

  • 冪等包括第一次請求的時候對資源產生了副作用,但是以后的多次請求都不會再對資源產生副作用。
  • 冪等關注的是以后的多次請求是否對資源產生的副作用,而不關注結果。
  • 網絡超時等問題,不是冪等的討論范圍。
  • 冪等性是系統服務對外一種承諾,而不是實現,承諾只要調用接口成功,外部多次調用對系統的影響是一致的。聲明為冪等的服務會認為外部調用失敗是常態,并且失敗之后必然會有重試。

1.2 場景

業務開發時,可能會遇到由于網絡震蕩導致請求無法收到導致觸發了重試機制,或者前端抖動導致表單重復提交這樣的情況。比如在交易系統中,用戶提交購物請求已經被服務器端正確處理,但服務器端的返回結果由于網絡等原因被掉丟了,導致客戶端無法得知處理結果。如果是在網頁上,一些不恰當的設計可能會使用戶認為上一次操作失敗了,然后刷新頁面,這就導致了扣款被調用兩次,賬戶也被多扣了一次錢。此時就需要引入冪等性接口了。

我們以MySQL為例,只有第三種場景需要開發人員使用其他策略保證冪等性:

  1. SELECT col1 FROM tab1 WHER col2=2;  
  2. -- 無論執行多少次都不會改變狀態,是天然的冪等。 
  3. UPDATE tab1 SET col1=1 WHERE col2=2;  
  4. -- 無論執行成功多少次狀態都是一致的,因此也是冪等操作。 
  5. UPDATE tab1 SET col1=col1+1 WHERE col2=2;  
  6. -- 每次執行的結果都會發生變化,這種不是冪等的。 

這里說下重復提交跟冪等性的區別:

  1. 重復提交是在第一次請求已經成功的情況下,人為的進行多次操作,導致不滿足冪等要求的服務多次改變狀態。
  2. 冪等更多使用的情況是第一次請求不知道結果(比如超時)或者失敗的異常情況下,發起多次請求,目的是多次確認第一次請求成功,卻不會因多次請求而出現多次的狀態變化。

1.3 冪等性思考

引入冪等性后會使得服務端邏輯更加復雜,滿足冪等性的服務需要在邏輯中至少包含兩點:

首先去查詢上一次的執行狀態,如果沒有則認為是第一次請求。

在服務改變狀態的業務邏輯前,保證防重復提交的邏輯。

冪等性可以簡化客戶端邏輯處理,但卻增加了服務提供者的邏輯和成本,所以是否要用,需根據具體場景具體分析,因此除了業務上的特殊要求外,盡量不提供冪等的接口。

增加了額外控制冪等的業務邏輯,復雜化了業務功能。

把并行執行的功能改為串行執行,降低了執行效率。

2 冪等性解決

2.1 前端設置

在用戶點擊完提交按鈕后,我們可以把按鈕設置為不可用或者隱藏狀態。

前端限制比較簡單,但有個致命錯誤,如果碰到懂行的用戶通過模擬網頁請求來重復提交請求,繞過了前端限制。

2.2 唯一索引

防止訂單多次插入的最簡單直接方法就是創建唯一索引,然后插入的時候可能語句有細微的不同。但目的都是保證相同記錄在數據庫中只存在一條。

  1. 方法一:給數據庫添加唯一索引,然后如果執行時捕捉到了DuplicateKeyException會明白是重復插入導致的,繼續往下執行業務即可。
  2. 方法二:利用MySQL自帶的關鍵字ON DUPLICATE KEY UPDATE 實現不存在則插入,存在則更新的操作,該關鍵字不會刪除原有的記錄。
  3. 方法三:replace into 主要作用類似 INSERT 插入操作,replace into底層是先刪除后插入數據,會破壞索引、重新維護索引。需注意必須要有主鍵或唯一索引才能有效,否則replace into就只新增了。

2.3 去重表

去重表的機制是根據mysql唯一索引的特性來的,大致流程:

  1. 客戶端先請求服務端,服務端先將這次的請求信息存入一張mysql的去重表中,這張表要根據這次請求的其中某個特殊字段建立唯一索引,或者主鍵索引。
  2. 判斷是否插入成功,如果插入成功,則繼續做后續業務請求。如果插入失敗,則代表已經執行過當前請求。

2.4 悲觀鎖

方式一:簡單的利用Java自帶的syn 或 lock 鎖實現冪等性。核心點在于將重要的執行部分將并行切換為串行。缺點是這個鎖在分布式場景是不能用的,因為都跨JVM了!此時需要引入分布式鎖了。

依靠MySQL自帶的for update操作數據庫,來實現串行化。這里的重點在于for update,簡單說明下:

  1. 當線程A執行for update,數據會對當前記錄加鎖,其他線程執行到此行代碼的時候,會等待線程A釋放鎖之后,才可以獲取鎖,繼續后續操作。
  2. 事物提交時,for update獲取的鎖會自動釋放。

該模式的缺點是,如果業務處理比較耗時,并發情況下,后面線程會長期處于等待狀態,占用了很多線程,讓這些線程處于無效等待狀態,而web服務中的線程數量一般有限的,如果大量線程由于獲取for update鎖處于等待狀態,不利于系統并發操作。

2.5 樂觀鎖

對每行數據添加個version字段,這里其實跟秒殺設計中的思路類似,利用MySQL自帶的當前讀更新操作。在更新數據時候先查詢獲得對應版本號,然后嘗試update操作,根據返回值是否為0來確保是否是重復提交。

  1. select id,name,account,version from user where id = 1412; // 假設獲得的 version = 10 
  2.  
  3. update user set account = account + 10,version = version + 1  
  4. where id = 1412 and version = 10; 

2.6 分布式鎖

使用Redis中的setnx操作,將冪等性的保證屏障設置在分布式鎖中。如果setnx成功了說明這是第一次進行數據插入,繼續執行SQL語句即可。如果setnx失敗了,那說明已經執行過了。

2.7 token 方案

這種方式分成兩個階段:申請token階段和支付階段。

  1. 第一階段:在進入到提交訂單頁面之前,需要訂單系統根據用戶信息向支付系統發起一次申請token的請求,支付系統將token保存到Redis緩存中,為第二階段支付使用。
  2. 第二階段:訂單系統拿著申請到的token發起支付請求,支付系統會檢查Redis中是否存在該token,如果存在,表示第一次發起支付請求,刪除緩存中token后開始支付邏輯處理;如果緩存中不存在,表示非法請求。

實際上這里的token可以認為是一個信物,支付系統根據token確認插入的唯一性。token模式不足之處在于,需要系統間交互兩次,流程較上述方法復雜。

token

參考

MySQL操作:https://blog.csdn.net/qq_18975791/article/details/107285455

蘇三說冪等:https://mp.weixin.qq.com/s/v4CamZlqHP8gEmubzPme4g

冪等性實現:https://blog.csdn.net/wanglei303707/article/details/88298211

 

責任編輯:武曉燕 來源: sowhat1412
相關推薦

2021-03-28 09:45:05

冪等性接口數據

2024-03-13 15:18:00

接口冪等性高并發

2023-09-01 15:27:31

2020-07-15 08:14:12

高并發

2025-02-26 08:20:18

2021-01-18 14:34:59

冪等性接口客戶端

2023-10-26 07:32:42

2024-07-10 12:23:10

2020-10-18 07:25:55

MQ消息冪等架構

2017-04-03 21:23:44

消息總線冪等性消息

2022-01-04 12:08:46

設計接口

2024-11-01 09:28:02

2024-06-07 09:06:36

2025-01-20 10:22:23

2023-08-29 13:53:00

前端攔截HashMap

2021-06-02 17:58:49

腳手架 冪等性前端

2021-01-13 11:23:59

分布式冪等性支付

2025-03-17 08:07:11

2024-07-03 11:59:40

2025-02-23 08:00:00

冪等性Java開發
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 欧美夜夜 | www.4567| 黄色网址大全在线观看 | h视频免费在线观看 | 韩国主播午夜大尺度福利 | 成人黄色电影免费 | 久久精品国产久精国产 | 波多野结衣一区二区三区在线观看 | 美女张开腿露出尿口 | 亚洲精品自在在线观看 | 欧美5区| av网址在线播放 | 色婷婷综合久久久中字幕精品久久 | 91麻豆精品一区二区三区 | 在线观看www高清视频 | 综合久久网 | 日韩精品一区二区三区视频播放 | 中文字幕在线观看第一页 | 青青草免费在线视频 | 国产精品成人在线播放 | 欧洲成人免费视频 | 国产精品99久久久久久www | 成人在线不卡 | 免费成人国产 | 国产成人免费 | 亚洲精品久 | 成人婷婷 | 国产精品免费看 | 国产一级一级国产 | 欧美一区二区三区免费电影 | 婷婷五月色综合 | 国产欧美三区 | 成人av一区二区亚洲精 | 特黄色一级毛片 | 99综合在线 | 超碰97人人人人人蜜桃 | 久久国产欧美日韩精品 | 国产黄色网址在线观看 | 国产一二三视频在线观看 | 亚洲91精品| 欧美一级高清片 |