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