如何確保分布式場(chǎng)景下的并發(fā)冪等性?

Java技術(shù)棧
www.javastack.cn
關(guān)注閱讀更多優(yōu)質(zhì)文章
本文作者:_BKing
博客地址:https://www.cnblogs.com/xiaowei123
冪等是什么 ?
冪等是數(shù)學(xué)中的一個(gè)概念,它表示如果一個(gè)東西進(jìn)行1次變換或進(jìn)行N次變換之后,所產(chǎn)生的效果如果相同的話,就稱為冪等。
在程序上,如果我們使用相同的請(qǐng)求調(diào)用這個(gè)接口一次和調(diào)用這個(gè)接口多次,對(duì)系統(tǒng)所產(chǎn)生的影響是相同的。如果一個(gè)接口滿足這個(gè)特性,那么我們就說(shuō)這個(gè)接口是冪等的。
這里我用些例子來(lái)說(shuō)說(shuō):
1. 用戶禮包領(lǐng)取
我們都知道一個(gè)用戶新注冊(cè)的時(shí)候,系統(tǒng)都會(huì)送該用戶一份新用戶大禮包,當(dāng)我們點(diǎn)擊領(lǐng)取這個(gè)禮包之后,我們就相當(dāng)于收下了這份禮包,以后無(wú)論你怎么點(diǎn)擊領(lǐng)取,結(jié)果還是一樣,系統(tǒng)只會(huì)提示你已經(jīng)領(lǐng)取過(guò)該禮包了,不會(huì)再讓你重復(fù)領(lǐng)取一次。
2. 搶紅包
當(dāng)我們?cè)趽屢环菁t包的時(shí)候,我們點(diǎn)擊了搶,搶到就有,沒(méi)搶到就沒(méi)有,之后,無(wú)論我們重復(fù)點(diǎn)擊多少次,紅包都會(huì)提示你已經(jīng)搶過(guò)該紅包了。
3. 賬單付款
當(dāng)我們要結(jié)賬的時(shí)候,支付平臺(tái)會(huì)生成唯一的支付連接,不會(huì)再次生成另外的支付連接。(不能因?yàn)檫@個(gè)支付接口被調(diào)了兩次就創(chuàng)建兩個(gè)一樣的訂單。)
N. ......
冪等機(jī)制的核心是保證資源唯一性,例如:客戶端重復(fù)提交或服務(wù)端的多次重試只會(huì)產(chǎn)生一份結(jié)果。
如:支付場(chǎng)景、退款場(chǎng)景,涉及金錢的交易不能出現(xiàn)多次扣款等問(wèn)題。
什么情況下需要冪等 ?
對(duì)于查詢這樣的接口,我們都知道,我們無(wú)論如何查詢數(shù)據(jù),都不會(huì)對(duì)原有的數(shù)據(jù)造成影響。因此不管調(diào)用多少次查詢接口,資源都不會(huì)改變,所以是它是冪等的。(我們不用考慮類似這樣的接口)
對(duì)于以相同的請(qǐng)求調(diào)用這個(gè)接口一次或多次,需要給調(diào)用方返回一致的結(jié)果時(shí),就要考慮將這個(gè)接口設(shè)計(jì)成冪等接口。
如何保證冪等呢 ?
對(duì)于需要保證冪等的前提,我們都知道是由于多次重復(fù)提交了相同的請(qǐng)求。要保證冪等的條件更多是在重復(fù)請(qǐng)求已經(jīng)發(fā)生了,這時(shí)我們要采取相應(yīng)措施來(lái)保證系統(tǒng)的正常。
這時(shí)我們要考慮一些條件和范圍,如:數(shù)據(jù)的對(duì)象和范圍
這里推薦保證冪等機(jī)制的方法有:
1. 分布式鎖
2. 創(chuàng)建數(shù)據(jù)庫(kù)的唯一索引
3. 狀態(tài)機(jī) (通過(guò)狀態(tài)機(jī)來(lái)進(jìn)行狀態(tài)約束和狀態(tài)流轉(zhuǎn))
4. 先執(zhí)行 select,后執(zhí)行 insert 操作






關(guān)注Java技術(shù)棧看更多干貨



