基於消息隊列實現分布式事務


基於消息隊列實現分布式事務

場景:

訂單系統產生訂單,購物車系統減購物車中的商。

實現思路 :

  1. 訂單系統在消息隊列上開啟一個事務(沒有創建訂單)。
  2. 訂單系統給消息服務器發送一個“半消息”,這個半消息不是說消息內容不完整,它包含的內容就是完整的消息內容,半消息和普通消息的唯一區別是,在事務提交之前,對於消費者來說,這個消息是不可見的。
  3. 半消息發送成功后,訂單系統就可以執行本地事務了,在訂單庫中創建一條訂單記錄,並提交訂單庫的數據庫事務。
  4. 然后根據本地事務的執行結果決定提交或者回滾事務消息。如果訂單創建成功,那就提交事務消息,購物車系統就可以消費到這條消息繼續后續的流程。如果訂單創建失敗,那就回滾事務消息,購物車系統就不會收到這條消息。

橙色和綠色分別是兩個事務。

問題:

步驟4事務提交失敗;這時候訂單系統本地事務已提交爾購物車系統沒有收到消息,造成數據不一致。

如何解決消息隊列事務提交過程出現的異常:

kafka會直接拋出異常用戶自行處理;

在RocketMQ中的事務實現中,增加了事務反查的機制來解決事務消息提交失敗的問題 , RocketMQ的Broker沒有收到提交或者回滾的請求,Broker會定期去producer上反查這個事務對應的本地事務的狀態,然后根據反查結果決定提交或者回滾這個事務。

為了支持事務反查機制,我們的業務代碼需要實現一個反查本地事務狀態的接口告知RocketMQ本地事務是成功還是失敗。

本例中的反查邏輯很簡單只需根據消息中的訂單ID,在訂單庫中查詢訂單是否存在即可。

能不能在訂單創建完成后再向消息隊列發送訂單數據?這樣不用考慮訂單創建失敗而發送消息的情況了

考慮這樣一種情況:訂單創建成功了,還沒來得及發消息,這個節點突然斷電了。

還有一種情況訂單創建成功,減購物車(后續操作)失敗的話要寫實物補償把創建的訂單刪掉。

能不能這樣:

1.開啟本地事務創建訂單,2.發消息,3.根據發消息是否成功來決定提交還是回滾本地事務。這樣不需要事務消息也能解決這個場景的問題了?

如果本地事務提交失敗已發送的消息無法撤回,會導致數據不一致。

小結

不論是消息隊列事務還是異步事務都遵循事務的四大特性:原子性,一致性,隔離性,持久性。

更多實現分布式事務的方法: https://blog.csdn.net/ityqing/article/details/102655827


**** 碼字不易如果對你有幫助請給個關注****

**** 愛技術愛生活 QQ群: 894109590****


免責聲明!

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



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