分布式事務(3)---RocketMQ實現分布式事務原理


分布式事務(3)—RocketMQ實現分布式事務原理

之前講過有關分布式事務2PC、3PC、TCC的理論知識,博客地址:

1、分布式事務(1)---2PC和3PC原理

2、分布式事務(2)---TCC原理

這篇講有關RocketMQ實現分布式事務的理論知識,下篇也會示例 通過SpringCloud來實例RocketMQ實現分布式事務的項目。

一、舉個分布式事務場景

列子:假設 AB100塊錢,同時它們不是同一個服務上。

目標:就是 A 減100塊錢,B 加100塊錢。

實際情況可能有四種:

1)就是A賬戶減100 (成功),B賬戶加100 (成功)

2)就是A賬戶減100(失敗),B賬戶加100 (失敗)

3)就是A賬戶減100(成功),B賬戶加100 (失敗)

4)就是A賬戶減100 (失敗),B賬戶加100 (成功)

這里 第1和第2 種情況是能夠保證事務的一致性的,但是 第3和第4 是無法保證事務的一致性的。

那我們來看下RocketMQ是如何來保證事務的一致性的。


二、RocketMQ實現分布式事務原理

RocketMQ雖然之前也支持分布式事務,但並沒有開源,等到RocketMQ 4.3才正式開源。

1、基礎概念

最終一致性

RocketMQ是一種最終一致性的分布式事務,就是說它保證的是消息最終一致性,而不是像2PC、3PC、TCC那樣強一致分布式事務,至於為什么說它是最終一致性事務下面會詳細說明。

Half Message(半消息)

是指暫不能被Consumer消費的消息。Producer 已經把消息成功發送到了 Broker 端,但此消息被標記為暫不能投遞狀態,處於該種狀態下的消息稱為半消息。需要 Producer

對消息的二次確認后,Consumer才能去消費它。

消息回查

由於網絡閃段,生產者應用重啟等原因。導致 Producer 端一直沒有對 Half Message(半消息) 進行 二次確認。這是Brock服務器會定時掃描長期處於半消息的消息,會

主動詢問 Producer端 該消息的最終狀態(Commit或者Rollback),該消息即為 消息回查

2、分布式事務交互流程

理解這張阿里官方的圖,就能理解RocketMQ分布式事務的原理了。

我們來說明下上面這張圖

1、A服務先發送個Half Message給Brock端,消息中攜帶 B服務 即將要+100元的信息。

2、當A服務知道Half Message發送成功后,那么開始第3步執行本地事務。

3、執行本地事務(會有三種情況1、執行成功。2、執行失敗。3、網絡等原因導致沒有響應)

4.1)、如果本地事務成功,那么Product像Brock服務器發送Commit,這樣B服務就可以消費該message。

4.2)、如果本地事務失敗,那么Product像Brock服務器發送Rollback,那么就會直接刪除上面這條半消息。

4.3)、如果因為網絡等原因遲遲沒有返回失敗還是成功,那么會執行RocketMQ的回調接口,來進行事務的回查。

從上面流程可以得知 只有A服務本地事務執行成功 ,B服務才能消費該message

然后我們再來思考幾個問題?

為什么要先發送Half Message(半消息)

我覺得主要有兩點

1)可以先確認 Brock服務器是否正常 ,如果半消息都發送失敗了 那說明Brock掛了。

2)可以通過半消息來回查事務,如果半消息發送成功后一直沒有被二次確認,那么就會回查事務狀態。

什么情況會回查

也會有兩種情況

1)執行本地事務的時候,由於突然網絡等原因一直沒有返回執行事務的結果(commit或者rollback)導致最終返回UNKNOW,那么就會回查。

2) 本地事務執行成功后,返回Commit進行消息二次確認的時候的服務掛了,在重啟服務那么這個時候在brock端
   它還是個Half Message(半消息),這也會回查。

特別注意: 如果回查,那么一定要先查看當前事務的執行情況,再看是否需要重新執行本地事務。

想象下如果出現第二種情況而引起的回查,如果不先查看當前事務的執行情況,而是直接執行事務,那么就相當於成功執行了兩個本地事務。

為什么說MQ是最終一致性事務

通過上面這幅圖,我們可以看出,在上面舉例事務不一致的兩種情況中,永遠不會發生

A賬戶減100 (失敗),B賬戶加100 (成功)

因為:如果A服務本地事務都失敗了,那B服務永遠不會執行任何操作,因為消息壓根就不會傳到B服務。

那么 A賬戶減100 (成功),B賬戶加100 (失敗) 會不會可能存在的。

答案是會的

因為A服務只負責當我消息執行成功了,保證消息能夠送達到B,至於B服務接到消息后最終執行結果A並不管。

那B服務失敗怎么辦?

如果B最終執行失敗,幾乎可以斷定就是代碼有問題所以才引起的異常,因為消費端RocketMQ有重試機制,如果不是代碼問題一般重試幾次就能成功。

如果是代碼的原因引起多次重試失敗后,也沒有關系,將該異常記錄下來,由人工處理,人工兜底處理后,就可以讓事務達到最終的一致性。



只要自己變優秀了,其他的事情才會跟着好起來(上將7)


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM