mysql事務保證冪等 如何保證介面的冪等性

2021-10-18 03:10:28 字數 2107 閱讀 6329

什麼是冪等性

冪等性是系統服務對外一種承諾,承諾只要呼叫介面成功,外部多次呼叫對系統的影響是一致的。宣告為冪等的服務會認為外部呼叫失敗是常態,並且失敗之後必然會有重試。

什麼情況下需要冪等

以sql為例:

select col1 from tab1 wher col2=2,無論執行多少次都不會改變狀態,是天然的冪等。

update tab1 set col1=1 where col2=2,無論執行成功多少次狀態都是一致的,因此也是冪等操作。

update tab1 set col1=col1+1 where col2=2,每次執行的結果都會發生變化,這種不是冪等的。

insert into user(userid,name) values(1,'a') 如userid為唯一主鍵,即重複操作上面的業務,只會插入一條使用者資料,具備冪等性。

如userid不是主鍵,可以重複,那上面業務多次操作,資料都會新增多條,不具備冪等性。

delete from user where userid=1,多次操作,結果一樣,具備冪等性

如何保證冪等

token機制

1、服務端提供了傳送token的介面。我們在分析業務的時候,哪些業務是存在冪等問題的,就必須在執行業務前,先去獲取token,伺服器會把token儲存到redis中。

2、然後呼叫業務介面請求時,把token攜帶過去,一般放在請求頭部。

3、伺服器判斷token是否存在redis中,存在表示第一次請求,然後刪除token,繼續執行業務。

4、如果判斷token不存在redis中,就表示是重複操作,直接返回重複標記給client,這樣就保證了業務**,不被重複執行。

關鍵點 先刪除token,還是後刪除token。

後刪除token:如果進行業務處理成功後,刪除redis中的token失敗了,這樣就導致了有可能會發生重複請求,因為token沒有被刪除。這個問題其實是資料庫和快取redis資料不一致問題,後續會寫文章進行講解。

先刪除token:如果系統出現問題導致業務處理出現異常,業務處理沒有成功,介面呼叫方也沒有獲取到明確的結果,然後進行重試,但token已經刪除掉了,服務端判斷token不存在,認為是重複請求,就直接返回了,無法進行業務處理了。

先刪除token可以保證不會因為重複請求,業務資料出現問題。出現業務異常,可以讓呼叫方配合處理一下,重新獲取新的token,再次由業務呼叫方發起重試請求就ok了。

token機制缺點

業務請求每次請求,都會有額外的請求(一次獲取token請求、判斷token是否存在的業務)。其實真實的生產環境中,1萬請求也許只會存在10個左右的請求會發生重試,為了這10個請求,我們讓9990個請求都發生了額外的請求。

樂觀鎖機制

這種方法適合在更新的場景中,update t_goods set count = count -1 , version = version + 1 where good_id=2 and version = 1

根據version版本,也就是在操作庫存前先獲取當前商品的version版本號,然後操作的時候帶上此version號。我們梳理下,我們第一次操作庫存時,得到version為1,呼叫庫存服務version變成了2;但返回給訂單服務出現了問題,訂單服務又一次發起呼叫庫存服務,當訂單服務傳如的version還是1,再執行上面的sql語句時,就不會執行;因為version已經變為2了,where條件就不成立。這樣就保證了不管呼叫幾次,只會真正的處理一次。

樂觀鎖主要使用於處理讀多寫少的問題

唯一主鍵

這個機制是利用了資料庫的主鍵唯一約束的特性,解決了在insert場景時冪等問題。但主鍵的要求不是自增的主鍵,這樣就需要業務生成全域性唯一的主鍵。

如果是分庫分表場景下,路由規則要保證相同請求下,落地在同乙個資料庫和同一表中,要不然資料庫主鍵約束就不起效果了,因為是不同的資料庫和表主鍵不相關。

防重表使用訂單號orderno做為去重表的唯一索引,把唯一索引插入去重表,再進行業務操作,且他們在同乙個事務中。這個保證了重複請求時,因為去重表有唯一約束,導致請求失敗,避免了冪等問題。這裡要注意的是,去重表和業務表應該在同一庫中,這樣就保證了在同乙個事務,即使業務操作失敗了,也會把去重表的資料回滾。這個很好的保證了資料一致性。

唯一id

呼叫介面時,生成乙個唯一id,redis將資料儲存到集合中(去重),存在即處理過。

如何保證介面的冪等性

冪等性是系統服務對外一種承諾,承諾只要呼叫介面成功,外部多次呼叫對系統的影響是一致的。宣告為冪等的服務會認為外部呼叫失敗是常態,並且失敗之後必然會有重試。以sql為例 select col1 from tab1 wher col2 2,無論執行多少次都不會改變狀態,是天然的冪等。update tab...

如何保證冪等性簡略梳理

保證冪等性 通過 邏輯實現 boolean pay int orderid,int accountid,bigdecimal amount order id 狀態流轉 update user order ua set ua.balance ua.balance 21,ua.order status ...

如何保證介面的冪等性

冪等性是系統服務對外一種承諾,承諾只要呼叫介面成功,外部多次呼叫對系統的影響是一致的。宣告為冪等的服務會認為外部呼叫失敗是常態,並且失敗之後必然會有重試。介面呼叫下存在的問題 現如今我們的系統大多拆分為分布式soa,或者微服務,一套系統中包含了多個子系統服務,而乙個子系統服務往往會去呼叫另乙個服務,...