分布式事务的解决思路与方案
導(dǎo)航
- 一、事務(wù)的種類(lèi)與場(chǎng)景
- 二、分布式事務(wù)解決方案
- 2.1 全局事務(wù)
- 2.2 可靠消息事務(wù)
- 2.3 最大努力通知
- 2.4 TCC 事務(wù)
 
- 三、TCC 模式常見(jiàn)問(wèn)題
- 3.1 二階段冪等
- 3.2 空回滾
- 3.3 資源懸掛
 
一、事務(wù)的種類(lèi)與場(chǎng)景
本地事務(wù)實(shí)際上就是指數(shù)據(jù)庫(kù)的事務(wù),參考《MySQL —— 事務(wù)與隔離級(jí)別總結(jié)》
分布式事務(wù)指的是在分布式環(huán)境下,由多個(gè)本地事務(wù)組成,多個(gè)系統(tǒng)之間如何保證事務(wù)之間的原子性、一致性等問(wèn)題。例如多個(gè)系統(tǒng)訪(fǎng)問(wèn)同一個(gè)數(shù)據(jù)庫(kù),多個(gè)系統(tǒng)訪(fǎng)問(wèn)多個(gè)數(shù)據(jù)庫(kù),等等這些場(chǎng)景,都數(shù)據(jù)分布式事務(wù)的討論范圍。
二、分布式事務(wù)解決方案
介紹四個(gè)業(yè)界應(yīng)用比較廣泛的分布式解決方案:全局事務(wù)、可靠消息服務(wù)、最大努力通知、TCC事務(wù)(補(bǔ)償型事務(wù))。
2.1 全局事務(wù)
全局事務(wù)基于DTP 模型實(shí)現(xiàn),這是由X/Open 組織提出的一種分布式事務(wù)模型,全稱(chēng)為“分布式事務(wù)處理參考模型”。
DTP規(guī)定要實(shí)現(xiàn)分布式事務(wù),需要三種角色:
AP:Application 應(yīng)用系統(tǒng)
 TM:Transaction Manager 事務(wù)管理器
 RM:Resource Manager 資源管理器
在 DTP 模型中,整個(gè)系統(tǒng)的事務(wù)分為兩個(gè)階段,即 2PC(2 Phrase Commit):
1、準(zhǔn)備階段:也可以叫表決階段或投票階段。TM 向 各個(gè) AP 發(fā)送準(zhǔn)備命令,并告訴各本地事務(wù)即將提交事務(wù)。TM同步等待參與者的響應(yīng)。此階段各本地事務(wù)已經(jīng)完成了事務(wù)邏輯,就差一步提交操作。
 2、提交階段:TM 根據(jù)響應(yīng)結(jié)果,決定發(fā)送提交或回滾命令。若都準(zhǔn)備成功,則提交事務(wù);但只要有一個(gè)返回失敗,就全部回滾。
 全局事務(wù)的優(yōu)缺點(diǎn):
優(yōu)點(diǎn):由于是同步阻塞協(xié)議,因此可以保證數(shù)據(jù)的強(qiáng)一致性。資源管理器本身就是數(shù)據(jù)庫(kù),實(shí)現(xiàn)不需要增加太多的代碼邏輯,實(shí)現(xiàn)成本低。流程簡(jiǎn)單。
 缺點(diǎn):
 1、單點(diǎn)故障問(wèn)題:TM 是全局事務(wù)的協(xié)調(diào)者、管理者,絕不能出現(xiàn)單點(diǎn)故障問(wèn)題。
 2、同步阻塞:增加了資源阻塞時(shí)間,可能存在死鎖的風(fēng)險(xiǎn),需要增加超時(shí)機(jī)制。
 3、一致性問(wèn)題:二階段提交可能存在失敗的情況,導(dǎo)致數(shù)據(jù)不一致。
總之,該模型是旨在保證強(qiáng)一致性的全局事務(wù)模型,但由于其模型仍然簡(jiǎn)單粗糙,在實(shí)際生產(chǎn)中,還需要進(jìn)一步擴(kuò)展和細(xì)化。
2.2 可靠消息事務(wù)
基于可靠消息服務(wù)的方案是通過(guò)消息中間件保證上、下游應(yīng)用數(shù)據(jù)操作的一致性。基本可以理解為就是 RocketMQ提供的事務(wù)消息,參考《Spring Cloud —— RocketMQ 的消息類(lèi)型》
假設(shè)有A和B兩個(gè)系統(tǒng),分別可以處理任務(wù)A和任務(wù)B。此時(shí)存在一個(gè)業(yè)務(wù)流程,需要將任務(wù)A和任務(wù)B在同一個(gè)事務(wù)中處理,就可以使用消息中間件來(lái)實(shí)現(xiàn)這種分布式事務(wù)。
 
2.3 最大努力通知
最大努力通知也被稱(chēng)為定期校對(duì),其實(shí)是對(duì)可靠消息事務(wù)方案的進(jìn)一步優(yōu)化。它引入了本地消息表來(lái)記錄錯(cuò)誤消息,然后加入失敗消息的定期校對(duì)功能,來(lái)進(jìn)一步保證消息會(huì)被下游系統(tǒng)消費(fèi)。
這種方案由于本身需要引入許多額外的補(bǔ)償結(jié)構(gòu),如本地消息表、失敗消息表、定期校對(duì)者等等,增加了業(yè)務(wù)耦合度,提高了實(shí)現(xiàn)復(fù)雜度,因此在業(yè)界并不是特別流行,但不得不說(shuō)的確是增加了系統(tǒng)事務(wù)的安全性降低了事故風(fēng)險(xiǎn)。
 
 第一步:消息由A系統(tǒng)投遞到中間件
1、處理業(yè)務(wù)的同一事務(wù)中,向本地消息表中寫(xiě)入一條記錄
 2、準(zhǔn)備專(zhuān)門(mén)的消息發(fā)送者,輪詢(xún)本地消息表,將需要發(fā)送的(未發(fā)送的或失敗的)事務(wù)消息發(fā)送到中間件
第二步:消息由中間件投遞到B系統(tǒng)
1、消息中間件收到消息后負(fù)責(zé)將該消息同步投遞到下游系統(tǒng),并觸發(fā)下游系統(tǒng)的任務(wù)執(zhí)行
 2、當(dāng)下游系統(tǒng)處理成功后,向消息中間件反饋確認(rèn)應(yīng)答,消息中間件便可以將該消息刪除,表示該事務(wù)完成
 3、如果投遞失敗,增加重試機(jī)制,對(duì)重試失敗的,寫(xiě)入錯(cuò)誤消息表
 4、消息中間件需要提供失敗消息的回查接口,下游系統(tǒng)會(huì)定期查詢(xún)失敗消息,自行消費(fèi)。
優(yōu)點(diǎn):一種非常經(jīng)典的分布式事務(wù)解決方案,最大限度保證最終一致性。
 缺點(diǎn):消息表會(huì)耦合到業(yè)務(wù)系統(tǒng)中,如果沒(méi)有封裝好的解決方案,會(huì)有很多雜活需要處理。
2.4 TCC 事務(wù)
TCC 即為 Try Confirm Cancel,它屬于補(bǔ)償型分布式事務(wù),業(yè)務(wù)層面的分布式事務(wù)。其中:
Try:指的是預(yù)留,即資源的預(yù)留和鎖定。
 Confirm:確認(rèn),其實(shí)就是真正的執(zhí)行提交。
 Cancel:撤銷(xiāo),就是回滾、撤銷(xiāo)鎖定動(dòng)作。
同樣,TCC模型也有一個(gè)全局的管理者或協(xié)調(diào)者角色,用來(lái)記錄TCC全局事務(wù)狀態(tài),并提交或回滾事務(wù)。
TCC模型的難點(diǎn)在于業(yè)務(wù)上的定義,對(duì)每一個(gè)操作都需要定義三個(gè)動(dòng)作分別對(duì)應(yīng) try-confirm-cancel例如,預(yù)留操作,需要明確預(yù)留或鎖定的業(yè)務(wù)資源。因此TCC是業(yè)務(wù)耦合型分布式事務(wù),需要根據(jù)特定的場(chǎng)景和業(yè)務(wù)邏輯來(lái)設(shè)計(jì)相應(yīng)的操作。另外,確認(rèn)或撤銷(xiāo)操作可能需要重試,因此需要保證操作的冪等。
TCC相較于2PC、3PC,其優(yōu)點(diǎn)在于可以跨數(shù)據(jù)庫(kù),跨業(yè)務(wù)來(lái)實(shí)現(xiàn)事務(wù),但缺點(diǎn)也顯而易見(jiàn),就是開(kāi)發(fā)量大,業(yè)務(wù)耦合度高。
TCC 兩階段提交與 XA 兩階段提交的區(qū)別:
XA 是資源層面的分布式事務(wù),強(qiáng)一致性,在兩階段提交的整個(gè)過(guò)程中,會(huì)一直持有資源的鎖。
 TCC 是業(yè)務(wù)層面的分布式事務(wù),最終一致性,不會(huì)一直持有資源的鎖。
三、TCC 模式常見(jiàn)問(wèn)題
TCC分布式事務(wù)模式其實(shí)屬于2PC的一種。其本身仍然存在一些繞不開(kāi)的問(wèn)題。
3.1 二階段冪等
由于網(wǎng)絡(luò)抖動(dòng),分布式事務(wù)框架可能會(huì)重復(fù)調(diào)用同一分布式事務(wù)中的一個(gè)分支事務(wù)的二階段方法(comfirm或cancel)。
 所以分支事務(wù)的二階段接口必須要保證冪等性,否則會(huì)產(chǎn)生資源的重復(fù)使用或重復(fù)釋放從而影響業(yè)務(wù)。
 對(duì)于冪等類(lèi)型的問(wèn)題,通常的手段是引入冪等查詢(xún)。例如,可以通過(guò)增加一張事務(wù)狀態(tài)表,包含如下幾個(gè)關(guān)鍵字段:
1.主事務(wù)id
 2.分支事務(wù)id,與主事務(wù)id作為聯(lián)合主鍵,唯一標(biāo)識(shí)一筆分支事務(wù)。
 3.分支事務(wù)狀態(tài):init(1),confirmed(2),rollbacked(3)
冪等記錄的插入時(shí)機(jī)是參與者的Try 方法,此時(shí)的分支事務(wù)狀態(tài)會(huì)被初始化為 init。然后當(dāng)二階段的 comfirm/canel 執(zhí)行時(shí)會(huì)將其狀態(tài)置為 comfirmed/rollbacked。
 當(dāng)TC重復(fù)調(diào)用二階段接口時(shí),參與者會(huì)先獲取事務(wù)狀態(tài)控制表對(duì)應(yīng)的記錄查看其事務(wù)狀態(tài)。如果狀態(tài)已為終態(tài)(confirmed或rollbacked),則直接將結(jié)果返回給TC,幫助其推進(jìn)分布式事務(wù),時(shí)序圖如下:
 
3.2 空回滾
空回滾指的是,在未收到 Try 請(qǐng)求的情況下收到 Cancel 請(qǐng)求。
如果不對(duì)空回滾加以防范的話(huà),可能會(huì)造成資源的無(wú)效釋放,即在沒(méi)有預(yù)留資源的情況下就釋放資源,造成故障。
針對(duì)空回滾,使用事務(wù)狀態(tài)控制表同樣有效。
當(dāng) Try 方法被成功執(zhí)行后,會(huì)插入一條分支事務(wù)記錄,當(dāng)后續(xù)二階段的 Cancel 方法執(zhí)行時(shí),如果記錄存在且狀態(tài)為 INIT,就表示一階段已成功執(zhí)行,可以正常執(zhí)行回滾,釋放預(yù)留資源;如果記錄不存在則表示一階段未執(zhí)行,本次為空回滾,不釋放任何資源。
一般情況下,是應(yīng)用是需要允許空回滾的。
3.3 資源懸掛
資源懸掛,意思是一階段Try 由于網(wǎng)絡(luò)超時(shí)或阻塞等原因,在二階段Cancel(Try超時(shí)事務(wù)管理器要Cancel全局事務(wù))之后執(zhí)行,即 Cancel --> Try,造成服務(wù)或資源懸掛。
可以看到,資源懸掛的前提是空回滾。因?yàn)橐浑A段Try超時(shí),事務(wù)管理器必須執(zhí)行回滾操作,這就造成了參與者一定會(huì)先收到 Cancel ,即空回滾。
視實(shí)際業(yè)務(wù)場(chǎng)景而定,一般會(huì)允許空回滾的情況,但要避免懸掛。可以在空回滾后,向事務(wù)狀態(tài)控制表中插入一條 狀態(tài)為 ROLLBACKED 的分支事務(wù)記錄,然后在 Try 的時(shí)候要增加對(duì)冪等的處理(可以依賴(lài)于數(shù)據(jù)庫(kù)的唯一約束),這樣,由于網(wǎng)絡(luò)原因而超時(shí)的 Try 請(qǐng)求就會(huì)自動(dòng)失敗,從而放棄調(diào)本次TCC事務(wù)。
總結(jié)
以上是生活随笔為你收集整理的分布式事务的解决思路与方案的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
 
                            
                        - 上一篇: js将object转化为json数据,j
- 下一篇: python寻找多数元素_寻找多数元素
