解決方案
-
本地消息表
本地消息表的關鍵在於本地有一張存儲消息日誌的記錄表,需要啓動一個定時任務去不停地掃描消息日誌記錄,確保消息能夠被髮送。具體流程如下圖:
上圖流程:
1)事務發起方本地事務執行成功,在本地消息表中記錄消息日誌。
2)啓動定時任務,循環掃描本地消息表。
3)定時任務掃描到消息則發送消息到消息中間件。
4)消息中間件收到消息,成功返回消息發送成功通知給事務發起方。
5)事務發起方收到消息發送成功則刪除日誌消息。
6)事務參與方訂閱消息,消費消息。
7)事務參與方處理本地事務。
2、RocketMq事務消息方案
Apache RocketMQ
4.3之後的版本正式支持事務消息
,爲分佈式事務實現提供了便利性支持。在RocketMQ 4.3後實現了完整的事務消息,實際上其實是對本地消息表的一個封裝
,將本地消息表移動到了MQ內部
,解決 Producer 端的消息發送與本地事務執行的原子性
問題。
實現流程:
1)事務發起方發送Half
事務消息
2)RocketMq回覆Half
發送成功
3)事務發起方執行本地事務
4)事務發起方執行本地事務成功,發送commit到RocketMq,mq投遞消息到事務參與方;事務發起方執行本地事務失敗,發送rollback
到RocketMq,mq刪除消息。
5)當RocketMq一定時間內未收到來自事務發起方的確認信息,會對事務發起方進行事務回查
。
6)事務發起方查詢本地事務狀態。
7)事務發起方根據查詢到的事務狀態發送commint/rollback
到RocketMq。
8)當RocketMq發起commit
後,收到失敗或一定時間未收到成功ack,則會發起重試。
總結:
優點
:
消息數據獨立存儲,降低業務系統與消息系統之間的耦合。
吞吐量優於本地消息表方案。
缺點
:
一次消息發送需要兩次網絡請求(half消息 + commit/rollback)。
需要實現消息回查接口。
其實每種分佈式事務的解決方案都有優劣,我們需要權衡利弊,選擇最合適業務場景的一種纔是王道!