TCC分布式事務(wù)七種異常情況小結(jié)
TCC標(biāo)準(zhǔn)編程模型
異常一:try階段異常
在try階段異常之后,就會(huì)執(zhí)行cancel階段,此時(shí)cancel階段是一定要保證成功的,如果cancel階段沒有執(zhí)行成功,那么就要進(jìn)行重試
異常二:cancel階段異常
其實(shí)這個(gè)異常的處理方式和異常一是一樣的,失敗了就重試,如果一直重試失敗,那么就要進(jìn)行人工干預(yù)
異常三:confirm提交異常
try階段成功了,那么confirm一定要成功,如果失敗了,那么就要進(jìn)行重試,重試多次還未成功,那么就要進(jìn)行人工干預(yù)
但是這里重試要注意,因?yàn)樵赾onfirm階段有二步數(shù)據(jù)庫操作,如果扣凍結(jié)張三20元成功了,但是李四加20元失敗了,這時(shí)候重試就要做判斷,看張三扣減20元是否之前已經(jīng)操作成功了,如果操作成功了,就不要再次進(jìn)行扣減凍結(jié)的操作
異常四:本地事務(wù)與TCC事務(wù)沖突
在try階段我們添加了一個(gè)本地事務(wù),如果這時(shí)候try階段異常,那么本地事務(wù)就會(huì)回滾,所以這時(shí)候凍結(jié)張三20元的操作就會(huì)回滾,也就不會(huì)被凍結(jié)。那么這時(shí)候try階段異常了,就會(huì)執(zhí)行cancel階段進(jìn)行回滾
在cancel階段,我們會(huì)還張三凍結(jié)的20元,這時(shí)候如果cancel執(zhí)行成功,那么張三的金額就會(huì)多出20元,就會(huì)造成數(shù)據(jù)的不一致,所以一般不要加本地事務(wù)
@Transaction(rollback=Exception.class) @Hmily(comfirmMethod="confirmMethod",cancelMethod="cancelMethod") public void try() { //查詢張三余額信息 Account account = accountMapper.selectByUserId(1); //凍結(jié)張三20元 account.setDJAccount(20); accountMapper.updateById(account); }
異常五:空回滾
為什么會(huì)有空回滾的異常呢? 比如我們在執(zhí)行try階段的時(shí)候,由于超時(shí)了,導(dǎo)致TCC就去執(zhí)行cancel階段了,但是這時(shí)候try階段還沒有執(zhí)行,也就是try階段還沒有凍結(jié)張三20元,這時(shí)候就造成了空回滾。
這時(shí)候我們需要引入其它手段,比如增加一張日志表,在回滾的時(shí)候,判斷一下這是事務(wù)有沒有執(zhí)行try階段,也就是這個(gè)事務(wù)有沒有執(zhí)行過try階段,如果沒有就不要執(zhí)行cancel階段的操作了。
異常六:第二階段重復(fù)提交
第二階段包括confirm,cancel,為什么會(huì)有重復(fù)提交呢? 因?yàn)槲覀儾荒鼙WCconfirm階段或者cancel階段一定能成功,如果不成功那么我們就要進(jìn)行重試,
舉個(gè)例子,在confirm階段有二步數(shù)據(jù)庫操作,假設(shè)扣減張三凍結(jié)20元成功,但是李四加20元失敗了,這時(shí)候我們就要進(jìn)行重試,但是重試的時(shí)候我們扣減張三凍結(jié)的20元已經(jīng)操作成功了,所以不需要再次扣減了,所以我們要做好類似去重的操作,之前操作成功的就不要再次進(jìn)行操作了
異常七:防懸掛
cancel階段比try階段先執(zhí)行,由于網(wǎng)絡(luò)原因?qū)е聇ry階段超時(shí),這時(shí)候就會(huì)執(zhí)行cancel階段操作,等cancel階段執(zhí)行完了,這時(shí)候try才執(zhí)行,雖然事務(wù)失敗了,但是這個(gè)事務(wù)已經(jīng)結(jié)束了,所以這時(shí)候的try方法一定不能執(zhí)行
以上就是TCC分布式事務(wù)七種異常情況小結(jié)的詳細(xì)內(nèi)容,更多關(guān)于TCC分布式事務(wù)異常的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Spring Boot2.0 @ConfigurationProperties使用詳解
這篇文章主要介紹了Spring Boot2.0 @ConfigurationProperties使用詳解,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2018-11-11基于Java快速實(shí)現(xiàn)一個(gè)簡單版的HashMap詳解
這篇文章主要為大家詳細(xì)介紹了如何利用Java簡單實(shí)現(xiàn)一個(gè)底層數(shù)據(jù)結(jié)構(gòu)為數(shù)組?+?鏈表的HashMap,不考慮鏈表長度超過8個(gè)時(shí)變?yōu)榧t黑樹的情況,需要的可以參考一下2023-02-02解決Spring JPA 使用@transaction注解時(shí)產(chǎn)生CGLIB代理沖突問題
這篇文章主要介紹了解決Spring JPA 使用@transaction注解時(shí)產(chǎn)生CGLIB代理沖突問題,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-08-08JAVA操作MongoDB數(shù)據(jù)庫實(shí)例教程
MongoDB是一個(gè)文檔型數(shù)據(jù)庫,是NOSQL家族中最重要的成員之一,下面這篇文章主要給大家介紹了關(guān)于JAVA操作MongoDB數(shù)據(jù)庫的相關(guān)資料,文中通過實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下2023-05-05SpringBoot配置線程池的實(shí)現(xiàn)示例
本文主要介紹了SpringBoot配置線程池的實(shí)現(xiàn)示例,主要包括在Spring Boot中創(chuàng)建和配置線程池,包括設(shè)置線程池的大小、隊(duì)列容量、線程名稱等參數(shù),感興趣的可以了解一下2023-09-09如何基于JWT實(shí)現(xiàn)接口的授權(quán)訪問詳解
授權(quán)是最常見的JWT使用場景,下面這篇文章主要給大家介紹了關(guān)于如何基于JWT實(shí)現(xiàn)接口的授權(quán)訪問的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),需要的朋友可以參考下2022-02-02java實(shí)現(xiàn)文件上傳下載至ftp服務(wù)器
這篇文章主要為大家詳細(xì)介紹了java實(shí)現(xiàn)文件上傳下載至ftp服務(wù)器的方法,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-06-06