軟件班級(jí)網(wǎng)站建設(shè)今日騰訊新聞最新消息
大家好,我是易安!今天我們談一談消息隊(duì)列中的事務(wù)消息這個(gè)話題。
一說起事務(wù),你可能自然會(huì)聯(lián)想到數(shù)據(jù)庫(kù)。我們?nèi)粘J褂檬聞?wù)的場(chǎng)景,絕大部分都是在操作數(shù)據(jù)庫(kù)的時(shí)候。像MySQL、Oracle這些主流的關(guān)系型數(shù)據(jù)庫(kù),也都提供了完整的事務(wù)實(shí)現(xiàn)。那消息隊(duì)列為什么也需要事務(wù)呢?
其實(shí)很多場(chǎng)景下,我們“發(fā)消息”這個(gè)過程,目的往往是通知另外一個(gè)系統(tǒng)或者模塊去更新數(shù)據(jù), 消息隊(duì)列中的“事務(wù)”,主要解決的是消息生產(chǎn)者和消息消費(fèi)者的數(shù)據(jù)一致性問題。
拿電商產(chǎn)品來舉個(gè)例子。一般來說,用戶在電商APP上購(gòu)物時(shí),先把商品加到購(gòu)物車?yán)?#xff0c;然后幾件商品一起下單,最后支付,完成購(gòu)物流程,就可以愉快地等待收貨了。
這個(gè)過程中有一個(gè)需要用到消息隊(duì)列的步驟,訂單系統(tǒng)創(chuàng)建訂單后,發(fā)消息給購(gòu)物車系統(tǒng),將已下單的商品從購(gòu)物車中刪除。因?yàn)閺馁?gòu)物車刪除已下單商品這個(gè)步驟,并不是用戶下單支付這個(gè)主要流程中必需的步驟,使用消息隊(duì)列來異步清理購(gòu)物車是更加合理的設(shè)計(jì)。

對(duì)于訂單系統(tǒng)來說,它創(chuàng)建訂單的過程中實(shí)際上執(zhí)行了2個(gè)步驟的操作:
-
在訂單庫(kù)中插入一條訂單數(shù)據(jù),創(chuàng)建訂單; -
發(fā)消息給消息隊(duì)列,消息的內(nèi)容就是剛剛創(chuàng)建的訂單。
購(gòu)物車系統(tǒng)訂閱相應(yīng)的主題,接收訂單創(chuàng)建的消息,然后清理購(gòu)物車,在購(gòu)物車中刪除訂單中的商品。
在分布式系統(tǒng)中,上面提到的這些步驟,任何一個(gè)步驟都有可能失敗,如果不做任何處理,那就有可能出現(xiàn)訂單數(shù)據(jù)與購(gòu)物車數(shù)據(jù)不一致的情況,比如說:
-
創(chuàng)建了訂單,沒有清理購(gòu)物車; -
訂單沒創(chuàng)建成功,購(gòu)物車?yán)锩娴纳唐穮s被清掉了。
那我們需要解決的問題可以總結(jié)為:在上述任意步驟都有可能失敗的情況下,還要保證訂單庫(kù)和購(gòu)物車庫(kù)這兩個(gè)庫(kù)的數(shù)據(jù)一致性。
對(duì)于購(gòu)物車系統(tǒng)收到訂單創(chuàng)建成功消息清理購(gòu)物車這個(gè)操作來說,失敗的處理比較簡(jiǎn)單,只要成功執(zhí)行購(gòu)物車清理后再提交消費(fèi)確認(rèn)即可,如果失敗,由于沒有提交消費(fèi)確認(rèn),消息隊(duì)列會(huì)自動(dòng)重試。
問題的關(guān)鍵點(diǎn)集中在訂單系統(tǒng),創(chuàng)建訂單和發(fā)送消息這兩個(gè)步驟要么都操作成功,要么都操作失敗,不允許一個(gè)成功而另一個(gè)失敗的情況出現(xiàn)。
這就是事務(wù)需要解決的問題。
什么是分布式事務(wù)?
那什么是事務(wù)呢?如果我們需要對(duì)若干數(shù)據(jù)進(jìn)行更新操作,為了保證這些數(shù)據(jù)的完整性和一致性,我們希望這些更新操作 要么都成功,要么都失敗。 至于更新的數(shù)據(jù),不只局限于數(shù)據(jù)庫(kù)中的數(shù)據(jù),可以是磁盤上的一個(gè)文件,也可以是遠(yuǎn)端的一個(gè)服務(wù),或者以其他形式存儲(chǔ)的數(shù)據(jù)。
這就是通常我們理解的事務(wù)。其實(shí)這段對(duì)事務(wù)的描述不是太準(zhǔn)確也不完整,但是,它更易于理解,大體上也是正確的。所以我還是傾向于這樣來講“事務(wù)”這個(gè)比較抽象的概念。
一個(gè)嚴(yán)格意義的事務(wù)實(shí)現(xiàn),應(yīng)該具有4個(gè)屬性:原子性、一致性、隔離性、持久性。這四個(gè)屬性通常稱為ACID特性。
-
原子性,是指一個(gè)事務(wù)操作不可分割,要么成功,要么失敗,不能有一半成功一半失敗的情況。
-
一致性,是指這些數(shù)據(jù)在事務(wù)執(zhí)行完成這個(gè)時(shí)間點(diǎn)之前,讀到的一定是更新前的數(shù)據(jù),之后讀到的一定是更新后的數(shù)據(jù),不應(yīng)該存在一個(gè)時(shí)刻,讓用戶讀到更新過程中的數(shù)據(jù)。
-
隔離性,是指一個(gè)事務(wù)的執(zhí)行不能被其他事務(wù)干擾。即一個(gè)事務(wù)內(nèi)部的操作及使用的數(shù)據(jù)對(duì)正在進(jìn)行的其他事務(wù)是隔離的,并發(fā)執(zhí)行的各個(gè)事務(wù)之間不能互相干擾,這個(gè)有點(diǎn)兒像我們打網(wǎng)游中的副本,我們?cè)诟北局写虻墓趾偷舻难b備,與其他副本沒有任何關(guān)聯(lián)也不會(huì)互相影響。
-
持久性,是指一個(gè)事務(wù)一旦完成提交,后續(xù)的其他操作和故障都不會(huì)對(duì)事務(wù)的結(jié)果產(chǎn)生任何影響。
大部分傳統(tǒng)的單體關(guān)系型數(shù)據(jù)庫(kù)都完整的實(shí)現(xiàn)了ACID,但是,對(duì)于分布式系統(tǒng)來說,嚴(yán)格的實(shí)現(xiàn)ACID這四個(gè)特性幾乎是不可能的,或者說實(shí)現(xiàn)的代價(jià)太大,大到我們無法接受。
分布式事務(wù)就是要在分布式系統(tǒng)中的實(shí)現(xiàn)事務(wù)。在分布式系統(tǒng)中,在保證可用性和不嚴(yán)重犧牲性能的前提下,光是要實(shí)現(xiàn)數(shù)據(jù)的一致性就已經(jīng)非常困難了,所以出現(xiàn)了很多變種版的一致性,比如順序一致性、最終一致性等等。
顯然實(shí)現(xiàn)嚴(yán)格的分布式事務(wù)是更加不可能完成的任務(wù)。所以,目前大家所說的分布式事務(wù),更多情況下,是在分布式系統(tǒng)中事務(wù)的不完整實(shí)現(xiàn)。在不同的應(yīng)用場(chǎng)景中,有不同的實(shí)現(xiàn),目的都是通過一些妥協(xié)來解決實(shí)際問題。
在實(shí)際應(yīng)用中,比較常見的分布式事務(wù)實(shí)現(xiàn)有2PC(Two-phase Commit,也叫二階段提交)、TCC(Try-Confirm-Cancel)和事務(wù)消息。每一種實(shí)現(xiàn)都有其特定的使用場(chǎng)景,也有各自的問題,都不是完美的解決方案。
這里我就重點(diǎn)講述下2PC的方式
兩階段提交方式解決分布式事務(wù)
兩階段提交協(xié)議為了保證分布在不同節(jié)點(diǎn)上的分布式事務(wù)的一致性,我們需要引入一個(gè)協(xié)調(diào)者來管理所有的節(jié)點(diǎn),負(fù)責(zé)各個(gè)本地資源的提交和回滾,并確保這些節(jié)點(diǎn)正確提交操作結(jié)果,若提交失敗則放棄事務(wù)。
XA 協(xié)議
XA 是一個(gè)分布式事務(wù)協(xié)議,規(guī)定了事務(wù)管理器和資源管理器接口。因此,XA 協(xié)議可以分為兩部分,即事務(wù)管理器和本地資源管理器。
-
事務(wù)管理器作為 協(xié)調(diào)者,負(fù)責(zé)各個(gè)本地資源的提交和回滾; -
資源管理器就是分布式 事務(wù)的參與者.其中資源管理通常是 數(shù)據(jù)庫(kù)。
基于 XA 協(xié)議的二階段提交方法中,二階段提交協(xié)議(The two-phase commit protocol,2PC),用于保證分布式系統(tǒng)中事務(wù)提交時(shí)的數(shù)據(jù)一致性,是 XA 在全局事務(wù)中用于協(xié)調(diào)多個(gè)資源的機(jī)制。
什么是二階段提交
分為投票和提交兩個(gè)階段。

投票為第一階段:
-
1 協(xié)調(diào)者(Coordinator,即事務(wù)管理器)會(huì)向事務(wù)的參與者(Cohort,即本地資源管理器)發(fā)起執(zhí)行操作的 CanCommit 請(qǐng)求,并等待參與者的響應(yīng). -
2 參與者接收到請(qǐng)求后,會(huì)執(zhí)行請(qǐng)求中的事務(wù)操作,記錄日志信息(包含事務(wù)執(zhí)行前的鏡像),同時(shí)鎖定當(dāng)前記錄。參與者執(zhí)行成功,則向協(xié)調(diào)者發(fā)送“Yes”消息,表示同意操作;若不成功,則發(fā)送“No”消息,表示終止操作。 -
3 當(dāng)所有的參與者都返回了操作結(jié)果(Yes 或 No 消息)后,系統(tǒng)進(jìn)入了提交階段。
提為第二階段:
協(xié)調(diào)者會(huì)根據(jù)所有參與者返回的信息向參與者發(fā)送 DoCommit 或 DoAbort 指令
-
若協(xié)調(diào)者收到的都是“Yes”消息,則向參與者發(fā)送“DoCommit”消息,參與者會(huì)完成剩余的操作并釋放資源,然后向協(xié)調(diào)者返回“HaveCommitted”消息; -
如果協(xié)調(diào)者收到的消息中包含“No”消息,則向所有參與者發(fā)送“DoAbort”消息,此時(shí)發(fā)送“Yes”的參與者則會(huì)根據(jù)之前執(zhí)行操作時(shí)的回滾日志對(duì)操作進(jìn)行回滾,然后所有參與者會(huì)向協(xié)調(diào)者發(fā)送“HaveCommitted”消息; -
協(xié)調(diào)者接收到“HaveCommitted”消息,就意味著整個(gè)事務(wù)結(jié)束了。
2PC問題
同步阻塞問題:二階段提交算法在執(zhí)行過程中,所有參與節(jié)點(diǎn)都是事務(wù)阻塞型的。也就是說,當(dāng)本地資源管理器占有臨界資源時(shí),其他資源管理器如果要訪問同一臨界資源,會(huì)處于阻塞狀態(tài)。
協(xié)調(diào)者單點(diǎn)故障導(dǎo)致參與者長(zhǎng)期阻塞問題:基于 XA 的二階段提交算法類似于集中式算法,一旦事務(wù)管理器發(fā)生故障,整個(gè)系統(tǒng)都處于停滯狀態(tài)。尤其是在提交階段,一旦事務(wù)管理器發(fā)生故障,資源管理器會(huì)由于等待管理器的消息,而一直鎖定事務(wù)資源,導(dǎo)致整個(gè)系統(tǒng)被阻塞。
數(shù)據(jù)不一致問題:在提交階段,當(dāng)協(xié)調(diào)者向參與者發(fā)送 DoCommit 請(qǐng)求之后,如果發(fā)生了局部網(wǎng)絡(luò)異常,或者在發(fā)送提交請(qǐng)求的過程中協(xié)調(diào)者發(fā)生了故障,就會(huì)導(dǎo)致只有一部分參與者接收到了提交請(qǐng)求并執(zhí)行提交操作,但其他未接到提交請(qǐng)求的那部分參與者則無法執(zhí)行事務(wù)提交。于是整個(gè)分布式系統(tǒng)便出現(xiàn)了數(shù)據(jù)不一致的問題。
二階段無法解決的問題:協(xié)調(diào)者再發(fā)出DoCommit 消息之后宕機(jī),而唯一接收到這條消息的參與者同時(shí)也宕機(jī)了。那么即使協(xié)調(diào)者通過選舉協(xié)議產(chǎn)生了新的協(xié)調(diào)者,這條事務(wù)的狀態(tài)也是不確定的,沒人知道事務(wù)是否被已經(jīng)提交。
3PC
三階段提交協(xié)議(Three-phase commit protocol,3PC),是對(duì)二階段提交(2PC)的改進(jìn)。為了解決兩階段提交的同步阻塞和數(shù)據(jù)不一致問題,三階段提交引入了超時(shí)機(jī)制和準(zhǔn)備階段。
超時(shí)機(jī)制
同時(shí)在協(xié)調(diào)者和參與者中引入超時(shí)機(jī)制。如果協(xié)調(diào)者或參與者在規(guī)定的時(shí)間內(nèi)沒有接收到來自其他節(jié)點(diǎn)的響應(yīng),就會(huì)根據(jù)當(dāng)前的狀態(tài)選擇提交或者終止整個(gè)事務(wù)。
準(zhǔn)備階段
在第一階段和第二階段中間引入了一個(gè)準(zhǔn)備階段,也就是在提交階段之前,加入了一個(gè)預(yù)提交階段。在預(yù)提交階段排除一些不一致的情況,保證在最后提交之前各參與節(jié)點(diǎn)的狀態(tài)是一致的。

CanCommit 階段
協(xié)調(diào)者向參與者發(fā)送請(qǐng)求操作(CanCommit 請(qǐng)求),詢問參與者是否可以執(zhí)行事務(wù)提交操作,然后等待參與者的響應(yīng);參與者收到 CanCommit 請(qǐng)求之后,回復(fù) Yes,表示可以順利執(zhí)行事務(wù);否則回復(fù) No。(我個(gè)人理解類似做TCC中Try操作)

PreCommit 階段
協(xié)調(diào)者根據(jù)參與者的回復(fù)情況,來決定是否可以進(jìn)行 PreCommit 操作 或 中斷事務(wù)。
如果所有參與者回復(fù)的都是“Yes”,那么協(xié)調(diào)者就會(huì)執(zhí)行事務(wù)的預(yù)執(zhí)行:
-
發(fā)送預(yù)提交請(qǐng)求。協(xié)調(diào)者向參與者發(fā)送 PreCommit 請(qǐng)求,進(jìn)入預(yù)提交階段。 -
事務(wù)預(yù)提交。參與者接收到 PreCommit 請(qǐng)求后執(zhí)行事務(wù)操作,并將 Undo 和 Redo 信息記錄到事務(wù)日志中,同時(shí)鎖定當(dāng)前記錄。 -
響應(yīng)反饋。如果參與者成功執(zhí)行了事務(wù)操作,則返回 ACK 響應(yīng),同時(shí)開始等待最終指令
如果任何一個(gè)參與者向協(xié)調(diào)者發(fā)送了“No”消息,或者等待超時(shí)之后,協(xié)調(diào)者都沒有收到參與者的響應(yīng),就執(zhí)行中斷事務(wù)的操作:
-
發(fā)送中斷請(qǐng)求。協(xié)調(diào)者向所有參與者發(fā)送“Abort”消息。 -
中斷事務(wù)。參與者收到“Abort”消息之后,或超時(shí)后仍未收到協(xié)調(diào)者的消息,執(zhí)行事務(wù)的中斷操作。

DoCommit 階段
協(xié)調(diào)者根據(jù)參與者的回復(fù)情況,來決定是否可以進(jìn)行 DoCommit 操作 或 中斷事務(wù)。
如果所有參與者回復(fù)的都是“Yes”,那么協(xié)調(diào)者就會(huì)執(zhí)行事務(wù)的提交:
-
發(fā)送提交請(qǐng)求。協(xié)調(diào)者接收到所有參與者發(fā)送的 Ack 響應(yīng),從預(yù)提交狀態(tài)進(jìn)入到提交狀態(tài),并向所有參與者發(fā)送 DoCommit 消息。 -
事務(wù)提交。參與者接收到 DoCommit 消息之后,正式提交事務(wù)。完成事務(wù)提交之后,釋放所有鎖住的資源。 -
響應(yīng)反饋。參與者提交完事務(wù)之后,向協(xié)調(diào)者發(fā)送 Ack 響應(yīng)。 -
完成事務(wù)。協(xié)調(diào)者接收到所有參與者的 Ack 響應(yīng)之后,完成事務(wù)。
如果任何一個(gè)參與者向協(xié)調(diào)者發(fā)送了“No”消息,或者協(xié)調(diào)者等待超時(shí)之后,協(xié)調(diào)者都沒有收到參與者的響應(yīng),就執(zhí)行中斷事務(wù)的操作:
-
發(fā)送中斷請(qǐng)求。協(xié)調(diào)者向所有參與者發(fā)送 Abort 請(qǐng)求。 -
事務(wù)回滾。參與者接收到 Abort 消息之后,利用其在 PreCommit 階段記錄的 Undo 信息執(zhí)行事務(wù)的回滾操作,并釋放所有鎖住的資源。 -
反饋結(jié)果。參與者完成事務(wù)回滾之后,向協(xié)調(diào)者發(fā)送 Ack 消息。 -
中斷事務(wù)。協(xié)調(diào)者接收到參與者反饋的 Ack 消息之后,執(zhí)行事務(wù)的中斷,并結(jié)束事務(wù)。 。
當(dāng)參與者PreCommit 階段向協(xié)調(diào)者發(fā)送 Ack 消息后,如果長(zhǎng)時(shí)間沒有得到協(xié)調(diào)者的響應(yīng),在默認(rèn)情況下,參與者會(huì)自動(dòng)將超時(shí)的事務(wù)進(jìn)行提交,不會(huì)像兩階段提交那樣被阻塞住

-
如何解決協(xié)調(diào)者單點(diǎn)故障導(dǎo)致參與者長(zhǎng)期阻塞。
由于存在超時(shí)機(jī)制,即使協(xié)調(diào)者發(fā)生故障,參與者無法及時(shí)收到來自協(xié)調(diào)者的信息之后,他會(huì)默認(rèn)執(zhí)行commit。避免參與者長(zhǎng)期阻塞。
-
同步阻塞問題
3PC會(huì)在2階段到3階段間阻塞,2PC會(huì)在1階段到2階段整個(gè)事務(wù)過程中阻塞,因而總體來說3PC并不能不阻塞,只是最大限度減少了阻塞的時(shí)間。同時(shí)安裝5.2也能夠解決協(xié)調(diào)者單點(diǎn)故障導(dǎo)致參與者長(zhǎng)期阻塞的問題
-
數(shù)據(jù)不一致問題
3PC和2PC都無法解決數(shù)據(jù)一致的問題,不過3PC存在超時(shí)會(huì)通過超時(shí)保證協(xié)調(diào)者和參與者在提交階段無法通信過程中最終一致,而不需人工介入。
可以看到不管是2階段提交還是3階段提交都是有些問題的,當(dāng)然我們還有消息隊(duì)列中的事務(wù)消息這種思路。事務(wù)消息適用的場(chǎng)景主要是那些需要異步更新數(shù)據(jù),并且對(duì)數(shù)據(jù)實(shí)時(shí)性要求不太高的場(chǎng)景。比如我們?cè)陂_始時(shí)提到的那個(gè)例子,在創(chuàng)建訂單后,如果出現(xiàn)短暫的幾秒,購(gòu)物車?yán)锏纳唐窙]有被及時(shí)清空,也不是完全不可接受的,只要最終購(gòu)物車的數(shù)據(jù)和訂單數(shù)據(jù)保持一致就可以了。
消息隊(duì)列如何實(shí)現(xiàn)分布式事務(wù)?
事務(wù)消息需要消息隊(duì)列提供相應(yīng)的功能才能實(shí)現(xiàn),Kafka和RocketMQ都提供了事務(wù)相關(guān)功能。
回到訂單和購(gòu)物車這個(gè)例子,我們一起來看下如何用消息隊(duì)列來實(shí)現(xiàn)分布式事務(wù),這里以RocketMQ來舉例。

首先,訂單系統(tǒng)在消息隊(duì)列上開啟一個(gè)事務(wù)。然后訂單系統(tǒng)給消息服務(wù)器發(fā)送一個(gè)“半消息”,這個(gè)半消息不是說消息內(nèi)容不完整,它包含的內(nèi)容就是完整的消息內(nèi)容,半消息和普通消息的唯一區(qū)別是,在事務(wù)提交之前,對(duì)于消費(fèi)者來說,這個(gè)消息是不可見的。
半消息發(fā)送成功后,訂單系統(tǒng)就可以執(zhí)行本地事務(wù)了,在訂單庫(kù)中創(chuàng)建一條訂單記錄,并提交訂單庫(kù)的數(shù)據(jù)庫(kù)事務(wù)。然后根據(jù)本地事務(wù)的執(zhí)行結(jié)果決定提交或者回滾事務(wù)消息。如果訂單創(chuàng)建成功,那就提交事務(wù)消息,購(gòu)物車系統(tǒng)就可以消費(fèi)到這條消息繼續(xù)后續(xù)的流程。如果訂單創(chuàng)建失敗,那就回滾事務(wù)消息,購(gòu)物車系統(tǒng)就不會(huì)收到這條消息。這樣就基本實(shí)現(xiàn)了“要么都成功,要么都失敗”的一致性要求。
如果你足夠細(xì)心,可能已經(jīng)發(fā)現(xiàn)了,這個(gè)實(shí)現(xiàn)過程中,有一個(gè)問題是沒有解決的。如果在第四步提交事務(wù)消息時(shí)失敗了怎么辦?對(duì)于這個(gè)問題,Kafka和RocketMQ給出了2種不同的解決方案。
Kafka的解決方案比較簡(jiǎn)單粗暴,直接拋出異常,讓用戶自行處理。我們可以在業(yè)務(wù)代碼中反復(fù)重試提交,直到提交成功,或者刪除之前創(chuàng)建的訂單進(jìn)行補(bǔ)償。RocketMQ則給出了另外一種解決方案。
RocketMQ中的分布式事務(wù)實(shí)現(xiàn)
在RocketMQ中的事務(wù)實(shí)現(xiàn)中,增加了事務(wù)反查的機(jī)制來解決事務(wù)消息提交失敗的問題。如果Producer也就是訂單系統(tǒng),在提交或者回滾事務(wù)消息時(shí)發(fā)生網(wǎng)絡(luò)異常,RocketMQ的Broker沒有收到提交或者回滾的請(qǐng)求,Broker會(huì)定期去Producer上反查這個(gè)事務(wù)對(duì)應(yīng)的本地事務(wù)的狀態(tài),然后根據(jù)反查結(jié)果決定提交或者回滾這個(gè)事務(wù)。
為了支撐這個(gè)事務(wù)反查機(jī)制,我們的業(yè)務(wù)代碼需要實(shí)現(xiàn)一個(gè)反查本地事務(wù)狀態(tài)的接口,告知RocketMQ本地事務(wù)是成功還是失敗。
在我們這個(gè)例子中,反查本地事務(wù)的邏輯也很簡(jiǎn)單,我們只要根據(jù)消息中的訂單ID,在訂單庫(kù)中查詢這個(gè)訂單是否存在即可,如果訂單存在則返回成功,否則返回失敗。RocketMQ會(huì)自動(dòng)根據(jù)事務(wù)反查的結(jié)果提交或者回滾事務(wù)消息。
這個(gè)反查本地事務(wù)的實(shí)現(xiàn),并不依賴消息的發(fā)送方,也就是訂單服務(wù)的某個(gè)實(shí)例節(jié)點(diǎn)上的任何數(shù)據(jù)。這種情況下,即使是發(fā)送事務(wù)消息的那個(gè)訂單服務(wù)節(jié)點(diǎn)宕機(jī)了,RocketMQ依然可以通過其他訂單服務(wù)的節(jié)點(diǎn)來執(zhí)行反查,確保事務(wù)的完整性。
綜合上面講的通用事務(wù)消息的實(shí)現(xiàn)和RocketMQ的事務(wù)反查機(jī)制,使用RocketMQ事務(wù)消息功能實(shí)現(xiàn)分布式事務(wù)的流程如下圖:

總結(jié)
本文通過一個(gè)訂單購(gòu)物車的例子,學(xué)習(xí)了事務(wù)的ACID四個(gè)特性,以及如何使用消息隊(duì)列來實(shí)現(xiàn)分布式事務(wù)。然后我給出了現(xiàn)有的幾種分布式事務(wù)的解決方案,包括事務(wù)消息,但是這幾種方案都不能解決分布式系統(tǒng)中的所有問題,每一種方案都有局限性和特定的適用場(chǎng)景。
最后,我們一起學(xué)習(xí)了RocketMQ的事務(wù)反查機(jī)制,這種機(jī)制通過定期反查事務(wù)狀態(tài),來補(bǔ)償提交事務(wù)消息可能出現(xiàn)的通信失敗。在Kafka的事務(wù)功能中,并沒有類似的反查機(jī)制,需要用戶自行去解決這個(gè)問題。但是,這不代表RocketMQ的事務(wù)功能比Kafka更好,只能說在我們這個(gè)例子的場(chǎng)景下,更適合使用RocketMQ。Kafka對(duì)于事務(wù)的定義、實(shí)現(xiàn)和適用場(chǎng)景,和RocketMQ有比較大的差異。
本文由 mdnice 多平臺(tái)發(fā)布