這篇文章主要介紹“什么是冪等性”,在日常操作中,相信很多人在什么是冪等性問題上存在疑惑,小編查閱了各式資料,整理出簡(jiǎn)單好用的操作方法,希望對(duì)大家解答”什么是冪等性”的疑惑有所幫助!接下來,請(qǐng)跟著小編一起來學(xué)習(xí)吧!
創(chuàng)新互聯(lián)建站是一家專業(yè)提供遂昌企業(yè)網(wǎng)站建設(shè),專注與成都網(wǎng)站建設(shè)、成都網(wǎng)站設(shè)計(jì)、成都h5網(wǎng)站建設(shè)、小程序制作等業(yè)務(wù)。10年已為遂昌眾多企業(yè)、政府機(jī)構(gòu)等服務(wù)。創(chuàng)新互聯(lián)專業(yè)網(wǎng)站制作公司優(yōu)惠進(jìn)行中。
冪等概念來自數(shù)學(xué),表示對(duì)數(shù)據(jù)源做N次變換和1次變換的結(jié)果是相同的。在工程中冪等性用來表示用戶對(duì)于同一操作發(fā)起的一次請(qǐng)求或者多次請(qǐng)求的結(jié)果是一致的,不會(huì)因?yàn)槎啻吸c(diǎn)擊而產(chǎn)生了副作用。
冪等包括第一次請(qǐng)求的時(shí)候?qū)Y源產(chǎn)生了副作用,但是以后的多次請(qǐng)求都不會(huì)再對(duì)資源產(chǎn)生副作用。
冪等關(guān)注的是以后的多次請(qǐng)求是否對(duì)資源產(chǎn)生的副作用,而不關(guān)注結(jié)果。
網(wǎng)絡(luò)超時(shí)等問題,不是冪等的討論范圍。
冪等性是系統(tǒng)服務(wù)對(duì)外一種承諾,而不是實(shí)現(xiàn),承諾只要調(diào)用接口成功,外部多次調(diào)用對(duì)系統(tǒng)的影響是一致的。聲明為冪等的服務(wù)會(huì)認(rèn)為外部調(diào)用失敗是常態(tài),并且失敗之后必然會(huì)有重試。
業(yè)務(wù)開發(fā)時(shí),可能會(huì)遇到由于網(wǎng)絡(luò)震蕩導(dǎo)致請(qǐng)求無法收到導(dǎo)致觸發(fā)了重試機(jī)制,或者前端抖動(dòng)導(dǎo)致表單重復(fù)提交這樣的情況。比如在交易系統(tǒng)中,用戶提交購(gòu)物請(qǐng)求已經(jīng)被服務(wù)器端正確處理,但服務(wù)器端的返回結(jié)果由于網(wǎng)絡(luò)等原因被掉丟了,導(dǎo)致客戶端無法得知處理結(jié)果。如果是在網(wǎng)頁(yè)上,一些不恰當(dāng)?shù)脑O(shè)計(jì)可能會(huì)使用戶認(rèn)為上一次操作失敗了,然后刷新頁(yè)面,這就導(dǎo)致了扣款被調(diào)用兩次,賬戶也被多扣了一次錢。此時(shí)就需要引入冪等性接口了。
我們以MySQL為例,只有第三種場(chǎng)景需要開發(fā)人員使用其他策略保證冪等性:
SELECT col1 FROM tab1 WHER col2=2; -- 無論執(zhí)行多少次都不會(huì)改變狀態(tài),是天然的冪等。 UPDATE tab1 SET col1=1 WHERE col2=2; -- 無論執(zhí)行成功多少次狀態(tài)都是一致的,因此也是冪等操作。 UPDATE tab1 SET col1=col1+1 WHERE col2=2; -- 每次執(zhí)行的結(jié)果都會(huì)發(fā)生變化,這種不是冪等的。
這里說下重復(fù)提交跟冪等性的區(qū)別:
鴻蒙官方戰(zhàn)略合作共建——HarmonyOS技術(shù)社區(qū)
重復(fù)提交是在第一次請(qǐng)求已經(jīng)成功的情況下,人為的進(jìn)行多次操作,導(dǎo)致不滿足冪等要求的服務(wù)多次改變狀態(tài)。
冪等更多使用的情況是第一次請(qǐng)求不知道結(jié)果(比如超時(shí))或者失敗的異常情況下,發(fā)起多次請(qǐng)求,目的是多次確認(rèn)第一次請(qǐng)求成功,卻不會(huì)因多次請(qǐng)求而出現(xiàn)多次的狀態(tài)變化。
引入冪等性后會(huì)使得服務(wù)端邏輯更加復(fù)雜,滿足冪等性的服務(wù)需要在邏輯中至少包含兩點(diǎn):
首先去查詢上一次的執(zhí)行狀態(tài),如果沒有則認(rèn)為是第一次請(qǐng)求。
在服務(wù)改變狀態(tài)的業(yè)務(wù)邏輯前,保證防重復(fù)提交的邏輯。
冪等性可以簡(jiǎn)化客戶端邏輯處理,但卻增加了服務(wù)提供者的邏輯和成本,所以是否要用,需根據(jù)具體場(chǎng)景具體分析,因此除了業(yè)務(wù)上的特殊要求外,盡量不提供冪等的接口。
增加了額外控制冪等的業(yè)務(wù)邏輯,復(fù)雜化了業(yè)務(wù)功能。
把并行執(zhí)行的功能改為串行執(zhí)行,降低了執(zhí)行效率。
在用戶點(diǎn)擊完提交按鈕后,我們可以把按鈕設(shè)置為不可用或者隱藏狀態(tài)。
前端限制比較簡(jiǎn)單,但有個(gè)致命錯(cuò)誤,如果碰到懂行的用戶通過模擬網(wǎng)頁(yè)請(qǐng)求來重復(fù)提交請(qǐng)求,繞過了前端限制。
防止訂單多次插入的最簡(jiǎn)單直接方法就是創(chuàng)建唯一索引,然后插入的時(shí)候可能語(yǔ)句有細(xì)微的不同。但目的都是保證相同記錄在數(shù)據(jù)庫(kù)中只存在一條。
鴻蒙官方戰(zhàn)略合作共建——HarmonyOS技術(shù)社區(qū)
方法一:給數(shù)據(jù)庫(kù)添加唯一索引,然后如果執(zhí)行時(shí)捕捉到了DuplicateKeyException會(huì)明白是重復(fù)插入導(dǎo)致的,繼續(xù)往下執(zhí)行業(yè)務(wù)即可。
方法二:利用MySQL自帶的關(guān)鍵字ON DUPLICATE KEY UPDATE 實(shí)現(xiàn)不存在則插入,存在則更新的操作,該關(guān)鍵字不會(huì)刪除原有的記錄。
方法三:replace into 主要作用類似 INSERT 插入操作,replace into底層是先刪除后插入數(shù)據(jù),會(huì)破壞索引、重新維護(hù)索引。需注意必須要有主鍵或唯一索引才能有效,否則replace into就只新增了。
去重表的機(jī)制是根據(jù)mysql唯一索引的特性來的,大致流程:
鴻蒙官方戰(zhàn)略合作共建——HarmonyOS技術(shù)社區(qū)
客戶端先請(qǐng)求服務(wù)端,服務(wù)端先將這次的請(qǐng)求信息存入一張mysql的去重表中,這張表要根據(jù)這次請(qǐng)求的其中某個(gè)特殊字段建立唯一索引,或者主鍵索引。
判斷是否插入成功,如果插入成功,則繼續(xù)做后續(xù)業(yè)務(wù)請(qǐng)求。如果插入失敗,則代表已經(jīng)執(zhí)行過當(dāng)前請(qǐng)求。
方式一:簡(jiǎn)單的利用Java自帶的syn 或 lock 鎖實(shí)現(xiàn)冪等性。核心點(diǎn)在于將重要的執(zhí)行部分將并行切換為串行。缺點(diǎn)是這個(gè)鎖在分布式場(chǎng)景是不能用的,因?yàn)槎伎鏙VM了!此時(shí)需要引入分布式鎖了。
依靠MySQL自帶的for update操作數(shù)據(jù)庫(kù),來實(shí)現(xiàn)串行化。這里的重點(diǎn)在于for update,簡(jiǎn)單說明下:
鴻蒙官方戰(zhàn)略合作共建——HarmonyOS技術(shù)社區(qū)
當(dāng)線程A執(zhí)行for update,數(shù)據(jù)會(huì)對(duì)當(dāng)前記錄加鎖,其他線程執(zhí)行到此行代碼的時(shí)候,會(huì)等待線程A釋放鎖之后,才可以獲取鎖,繼續(xù)后續(xù)操作。
事物提交時(shí),for update獲取的鎖會(huì)自動(dòng)釋放。
該模式的缺點(diǎn)是,如果業(yè)務(wù)處理比較耗時(shí),并發(fā)情況下,后面線程會(huì)長(zhǎng)期處于等待狀態(tài),占用了很多線程,讓這些線程處于無效等待狀態(tài),而web服務(wù)中的線程數(shù)量一般有限的,如果大量線程由于獲取for update鎖處于等待狀態(tài),不利于系統(tǒng)并發(fā)操作。
對(duì)每行數(shù)據(jù)添加個(gè)version字段,這里其實(shí)跟秒殺設(shè)計(jì)中的思路類似,利用MySQL自帶的當(dāng)前讀更新操作。在更新數(shù)據(jù)時(shí)候先查詢獲得對(duì)應(yīng)版本號(hào),然后嘗試update操作,根據(jù)返回值是否為0來確保是否是重復(fù)提交。
select id,name,account,version from user where id = 1412; // 假設(shè)獲得的 version = 10 update user set account = account + 10,version = version + 1 where id = 1412 and version = 10;
使用redis中的setnx操作,將冪等性的保證屏障設(shè)置在分布式鎖中。如果setnx成功了說明這是第一次進(jìn)行數(shù)據(jù)插入,繼續(xù)執(zhí)行SQL語(yǔ)句即可。如果setnx失敗了,那說明已經(jīng)執(zhí)行過了。
這種方式分成兩個(gè)階段:申請(qǐng)token階段和支付階段。
鴻蒙官方戰(zhàn)略合作共建——HarmonyOS技術(shù)社區(qū)
第一階段:在進(jìn)入到提交訂單頁(yè)面之前,需要訂單系統(tǒng)根據(jù)用戶信息向支付系統(tǒng)發(fā)起一次申請(qǐng)token的請(qǐng)求,支付系統(tǒng)將token保存到Redis緩存中,為第二階段支付使用。
第二階段:訂單系統(tǒng)拿著申請(qǐng)到的token發(fā)起支付請(qǐng)求,支付系統(tǒng)會(huì)檢查Redis中是否存在該token,如果存在,表示第一次發(fā)起支付請(qǐng)求,刪除緩存中token后開始支付邏輯處理;如果緩存中不存在,表示非法請(qǐng)求。
實(shí)際上這里的token可以認(rèn)為是一個(gè)信物,支付系統(tǒng)根據(jù)token確認(rèn)插入的唯一性。token模式不足之處在于,需要系統(tǒng)間交互兩次,流程較上述方法復(fù)雜。
到此,關(guān)于“什么是冪等性”的學(xué)習(xí)就結(jié)束了,希望能夠解決大家的疑惑。理論與實(shí)踐的搭配能更好的幫助大家學(xué)習(xí),快去試試吧!若想繼續(xù)學(xué)習(xí)更多相關(guān)知識(shí),請(qǐng)繼續(xù)關(guān)注創(chuàng)新互聯(lián)網(wǎng)站,小編會(huì)繼續(xù)努力為大家?guī)砀鄬?shí)用的文章!
網(wǎng)站名稱:什么是冪等性
文章網(wǎng)址:http://chinadenli.net/article4/gisdoe.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供營(yíng)銷型網(wǎng)站建設(shè)、網(wǎng)頁(yè)設(shè)計(jì)公司、品牌網(wǎng)站建設(shè)、搜索引擎優(yōu)化、網(wǎng)站設(shè)計(jì)公司、App設(shè)計(jì)
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)