給予消息隊列實現分佈式事務

給予消息隊列實現分佈式事務數據庫

場景:

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

實現思路 :

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

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

問題:

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

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

kafka會直接拋出異經常使用戶自行處理;.net

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

爲了支持事務反查機制,咱們的業務代碼須要實現一個反查本地事務狀態的接口告知RocketMQ本地事務是成功仍是失敗。blog

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

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

考慮這樣一種狀況:訂單建立成功了,還沒來得及發消息,這個節點忽然斷電了。隊列

還有一種狀況訂單建立成功,減購物車(後續操做)失敗的話要寫實物補償把建立的訂單刪掉。事務

能不能這樣:

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

若是本地事務提交失敗已發送的消息沒法撤回,會致使數據不一致。

小結

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

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


**** 碼字不易若是對你有幫助請給個關注****

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

相關文章
相關標籤/搜索