接口冪等性

1.什么是接口冪等
接口冪等性就是用戶對同一操作發(fā)起了一次或多次請求的對數(shù)據(jù)的影響是一致不變的系忙,不會因為多次的請求而產(chǎn)生副作用。

副作用:可以認為多次請求操作,每一次對數(shù)據(jù)狀態(tài)都會產(chǎn)生影響 。
注意這里并沒有要求接口返回結果是一致的唐片。

例如:update order set moeny = 100 where orderId = 2029282312
該操作無論執(zhí)行多少次丙猬,對數(shù)據(jù)的影響都是一致的,不變的费韭。

接口不做冪等處理會怎樣茧球?
支付場景:用戶購買商品后,發(fā)起支付操作星持,支付系統(tǒng)處理支付成功后抢埋,由于網(wǎng)絡原因沒有及時返回給用戶結果,其實這個時候訂單已經(jīng)扣過款督暂,相應的支付流水也都已經(jīng)生成揪垄,這個時候用戶又點擊支付操作,此時會進行第二次扣款逻翁,扣款成功后返回給用戶饥努。用戶去查看支付訂單和流水會發(fā)現(xiàn)自己支付兩次,完蛋了要用戶被投訴了八回,這就是接口沒有處理冪等造成的酷愧。

2.什么情況需要處理接口冪等性問題?
2.1 select 天然自帶冪等性缠诅。
每次查詢對數(shù)據(jù)都不會產(chǎn)生副作用溶浴。

2.2 insert 當我們重復插入數(shù)據(jù)的時候,會出現(xiàn)什么情況 管引?
第一種情況:自增主鍵士败,沒有冪等性。

eg:insert into product_info (id,name,type,price,tm)
執(zhí)行多次褥伴,會新增多條記錄拱烁。對結果集產(chǎn)生了副作用。

第二種情況:業(yè)務主鍵噩翠,具有冪等。

eg:insert into product_info (orderId,name,type,price,tm) orderId 為主鍵唯一
無論該sql執(zhí)行多少次邦投,對結果集產(chǎn)生的效果都是一樣只增加了一條數(shù)據(jù)伤锚。

2.3 delete 是否具有冪等性?
第一種情況:絕對刪除志衣,具有冪等性屯援。

eg;delete from order where id = 3 念脯。
無論該sql執(zhí)行多少次狞洋,對結果集產(chǎn)生的效果都是一樣只刪除了一條數(shù)據(jù)。

第二種情況: 相對刪除绿店,不具有冪等性吉懊。

eg:delete from order where id > 23 .
該操作每執(zhí)行一次庐橙,對結果集產(chǎn)生的結果,可能都不一樣借嗽,同一操作多次執(zhí)行對數(shù)據(jù)產(chǎn)生了副作用态鳖。

2.4 update 猜一猜是否具有天熱冪等性?
第一種情況:絕對更新恶导,具有冪等性浆竭。

eg:update good set stock= 586 where goodId = 10;
該操作無論執(zhí)行多少次操作對結果的影響都是一樣。

第二種情況:相對更新惨寿,不具有冪等性邦泄。

eg:update good set stock = stock+10 where goodid= 10 ;
每次執(zhí)行該操作庫存數(shù)量都會加10裂垦,所以不具備冪等操作顺囊。

總結:以上都是基于單庫,單表的操作冪等性的分析缸废,其實在具體業(yè)務當中包蓝,可能要設計多個表,多個庫企量,甚至跨服務操作测萎。比如分布式系統(tǒng)中,我們一個接口届巩,可能需要調(diào)用多個服務來完成任務硅瞧。那么這種情況,如何保證接口的冪等性呢?

接口冪等性解決方案
前言:接口冪等處理要根據(jù)具體業(yè)務來判斷怎么處理恕汇,以下會舉例來闡述接口冪等處理解決方案腕唧。

1.token+redis 機制
比如訂單支付場景:
該支付分為兩個步驟:
1.1 獲取全局唯一token
接口處理生成唯一標識(token) 存儲到redis中,并返回給調(diào)用客戶端瘾英。
1.2 發(fā)起支付操作并附帶token
接口處理:
1.2.1 獲得分布式鎖(處理并發(fā)情況)
1.2.2 判斷redis中是否存在token
1.2.3 存在 執(zhí)行支付業(yè)務邏輯枣接,否則返回該訂單已經(jīng)支付
1.2.4 釋放分布式鎖

思考:為什么要加分布式鎖?
原因1:在高并發(fā)請求中 缺谴,token判斷是否存在是非線程安全的但惶,所以要加分布式鎖來保證 該條件的判斷為線程安全
注釋:也可redis用刪除操作來判斷token,刪除成功代表token校驗通過 這個刪除是原子操作的

原因2:在支付業(yè)務中湿蛔,判斷支付訂單是否已經(jīng)存在膀曾,存在說明該訂單已經(jīng)支付過了,不存在就執(zhí)行扣款操作阳啥,如果相同操作并發(fā)兩個請求來到判斷條件可能兩個請求都能判斷支付訂單不存在添谊,造成重復扣款。 所以也要加分布式鎖保證線程的安全察迟。

2.CAS 保證接口冪等性

2.1 狀態(tài)機制冪等(狀態(tài)不可逆)
針對更新操作:
例如 電商訂單斩狱,訂單支付狀態(tài) 0 待支付 耳高, 1 支付中 , 3 支付成功 4 支付失敗喊废。

update order set status = 1 where status =0 and orderId = “201251487987”
該sql語句利用狀態(tài)CAS 保證該操作的冪等祝高。

    eg:比如要進行訂單支付,上來先用CAS更新訂單狀態(tài)污筷,
        返回影響說為1 代表修改成功工闺,可以支付,繼續(xù)執(zhí)行支付業(yè)務代碼
         返回影響數(shù) 0 代表修改失敗瓣蛀,該訂單已經(jīng)不是待支付訂單了陆蟆。

注釋:實際這里是利用CAS原理

3 樂觀鎖實現(xiàn)冪等
背景由來:

        為什么要有冪等這種場景?因為在大的系統(tǒng)中惋增,都是分布式部署叠殷,如:訂單業(yè)務 和 庫存業(yè)務有可能都是獨立部署的,都是單獨的服務诈皿。用戶下訂單林束,會調(diào)用到訂單服務和庫存服務。

比如:訂單系統(tǒng):
訂單服務 —> 庫存服務 (PRC遠程調(diào)用(服務接口))

    因為分布式部署稽亏,很有可能在調(diào)用庫存服務時壶冒,因為網(wǎng)絡等原因,訂單服務調(diào)用失敗截歉,但其實庫存服務已經(jīng)處理完成胖腾,只是返回給訂單服務處理結果時出現(xiàn)了異常。這個時候一般系統(tǒng)會作補償方案瘪松,也就是訂單服務再此放起庫存服務的調(diào)用,庫存減1

update t_goods set count = count -1 where good_id=2

      這樣就出現(xiàn)了問題咸作,其實上一次調(diào)用已經(jīng)減了1,只是訂單服務沒有收到處理結果∠溃現(xiàn)在又調(diào)用一次记罚,又要減1,這樣就不符合業(yè)務了壳嚎,多扣了桐智。

    冪等這個概念就是,不管庫存服務在相同條件下調(diào)用幾次诬辈,處理結果都一樣。這樣才能保證補償方案的可行性荐吉。

樂觀鎖方案
借鑒數(shù)據(jù)庫的樂觀鎖機制焙糟,如:
update t_goods set count = count -1 , version = version + 1 where good_id=2 and version = 1

4 防重表

1.利用數(shù)據(jù)庫建一張防重表(加唯一索引)

 比如訂單支付,
    反正重復支付:訂單號插入防重表 成功 執(zhí)行支付業(yè)務邏輯样屠,失敗說明已經(jīng)支付過穿撮。

防重表支付成功是否要刪除:
1.可定期清除數(shù)據(jù)
2.也可結合 訂單狀態(tài) 缺脉,在支付前查詢訂單狀態(tài)為待支付 執(zhí)行支付操作 ,操作后刪除訂單號 若 第二個請求插入防重表成功悦穿,但是這個時候查詢訂單狀態(tài)失敗攻礼。
(實際這個防重表就是實現(xiàn)了分布式鎖)

  1. 緩存隊列

將請求放入隊列,后續(xù)使用異步任務處理隊列中的數(shù)據(jù)栗柒,過濾掉重復的消息礁扮。 和防止重復消費道理是一樣。
————————————————
版權聲明:本文為CSDN博主「完美天空」的原創(chuàng)文章瞬沦,遵循CC 4.0 BY-SA版權協(xié)議太伊,轉(zhuǎn)載請附上原文出處鏈接及本聲明。
原文鏈接:https://blog.csdn.net/qq_29978863/article/details/107739744

?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末逛钻,一起剝皮案震驚了整個濱河市僚焦,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌曙痘,老刑警劉巖芳悲,帶你破解...
    沈念sama閱讀 210,978評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異边坤,居然都是意外死亡名扛,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 89,954評論 2 384
  • 文/潘曉璐 我一進店門惩嘉,熙熙樓的掌柜王于貴愁眉苦臉地迎上來罢洲,“玉大人,你說我怎么就攤上這事文黎∪敲纾” “怎么了?”我有些...
    開封第一講書人閱讀 156,623評論 0 345
  • 文/不壞的土叔 我叫張陵耸峭,是天一觀的道長桩蓉。 經(jīng)常有香客問我,道長劳闹,這世上最難降的妖魔是什么院究? 我笑而不...
    開封第一講書人閱讀 56,324評論 1 282
  • 正文 為了忘掉前任,我火速辦了婚禮本涕,結果婚禮上业汰,老公的妹妹穿的比我還像新娘。我一直安慰自己菩颖,他們只是感情好样漆,可當我...
    茶點故事閱讀 65,390評論 5 384
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著晦闰,像睡著了一般放祟。 火紅的嫁衣襯著肌膚如雪邑商。 梳的紋絲不亂的頭發(fā)上雇卷,一...
    開封第一講書人閱讀 49,741評論 1 289
  • 那天,我揣著相機與錄音,去河邊找鬼步做。 笑死跺株,一個胖子當著我的面吹牛空繁,可吹牛的內(nèi)容都是我干的把敞。 我是一名探鬼主播,決...
    沈念sama閱讀 38,892評論 3 405
  • 文/蒼蘭香墨 我猛地睜開眼执桌,長吁一口氣:“原來是場噩夢啊……” “哼鄙皇!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起仰挣,我...
    開封第一講書人閱讀 37,655評論 0 266
  • 序言:老撾萬榮一對情侶失蹤伴逸,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后膘壶,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體错蝴,經(jīng)...
    沈念sama閱讀 44,104評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,451評論 2 325
  • 正文 我和宋清朗相戀三年颓芭,在試婚紗的時候發(fā)現(xiàn)自己被綠了顷锰。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,569評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡亡问,死狀恐怖官紫,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情州藕,我是刑警寧澤束世,帶...
    沈念sama閱讀 34,254評論 4 328
  • 正文 年R本政府宣布,位于F島的核電站床玻,受9級特大地震影響毁涉,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜锈死,卻給世界環(huán)境...
    茶點故事閱讀 39,834評論 3 312
  • 文/蒙蒙 一贫堰、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧待牵,春花似錦其屏、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,725評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春睦优,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背壮不。 一陣腳步聲響...
    開封第一講書人閱讀 31,950評論 1 264
  • 我被黑心中介騙來泰國打工汗盘, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人询一。 一個月前我還...
    沈念sama閱讀 46,260評論 2 360
  • 正文 我出身青樓隐孽,卻偏偏與公主長得像,于是被迫代替她去往敵國和親健蕊。 傳聞我的和親對象是個殘疾皇子菱阵,可洞房花燭夜當晚...
    茶點故事閱讀 43,446評論 2 348

推薦閱讀更多精彩內(nèi)容

  • 1、什么是冪等性 冪等缩功,英文Idempotence 冪等這個詞原自數(shù)學晴及,冪等性是數(shù)學中的一個概念,常見于抽象代數(shù)中...
    Mr_Chao3閱讀 1,130評論 0 0
  • [前言] 接口冪等性問題嫡锌,對于開發(fā)人員來說虑稼,是一個跟語言無關的公共問題。本文分享了一些解決這類問題非常實用的辦法势木,...
    梅西愛騎車閱讀 900評論 0 10
  • 前言 接口冪等性問題啦桌,對于開發(fā)人員來說溯壶,是一個跟語言無關的公共問題。本文分享了一些解決這類問題非常實用的辦法甫男,絕大...
    蘇三說技術閱讀 239評論 1 1
  • 含義:接口可重復調(diào)用后且改,在調(diào)用方多次調(diào)用的情況下,接口最終得到的結果是一致的查剖。 有些接口天然具備冪等性钾虐,如查詢接口...
    劉敏_15da閱讀 1,769評論 0 0
  • 前言 接口冪等性問題,對于開發(fā)人員來說笋庄,是一個跟語言無關的公共問題效扫。本文分享了一些解決這類問題非常實用的辦法,絕大...
    timothyue1閱讀 109評論 0 1