如何利用事務消息實現分佈式事務

如何利用事務消息實現分佈式事務

一說起事務,容易聯想到數據庫。我們日常使用事務的場景,絕大部分都是在操作數據庫的時候。像 MySQL、Oracle這些主流的關係型數據庫,也都提供了完整的事務實現。

那消息隊列爲什麼也需要事務呢?

很多場景下,往往是一個模塊往另外一個模塊發消息的,往往需要另外一個系統接收到消息後更新數據,消息隊列中的 “事務”,主要解決的消息生產者與消費者之間的數據一致性問題

栗子

電商購物,用戶將商品添加到購物車,然後幾個商品一起下單,最後支付,完成購物流程,這過程在訂單系統創建訂單後,發送西峽縣給購物車系統,將已下單的商品從購物車中刪除,但是購物車刪除已下單商品這個步驟,並不是用戶下單支付主要流程的必須步驟,因此使用消息隊列來異步清理購物車是更加合理的設計。

業務場景

訂單系統

訂單系統,主要做了兩件事:

  1. 在訂單庫中插入一條訂單數據,創建訂單。
  2. 發消息給消息隊列,消息中的內容是剛創建的訂單。

購物車系統

購物車系統其實也主要做兩件事:

  1. 用戶將商品添加購物車時,購物車系統中新增一條商品數據。
  2. 購物車系統收到了訂單創建成功消息,清理已生成訂單的商品數據。

這樣就有一個需要解決的問題,需要保證訂單庫和購物車這兩個庫數據一致性。
需要保證購物車系統狀態是一致的,要麼都成功,要麼都失敗,不允許一個成功一個失敗的狀態。

事務的4個屬性

事務必須具有原子性,一致性,隔離性,持久性,也稱爲 ACID 特性。

  1. 原子性

原子性,指的是一個事務操作不可分割,要麼成功,要麼失敗,不能有一半成功,一半失敗的情況。

  1. 一致性

一致性,是指這些數據在事務執行完成這個時間點之前,讀到的一定是更新前的數據,之後讀到的一定更新後的數據,不應該存在一個時刻,讓用戶讀到更新過程中的數據。

  1. 隔離型

隔離性,是指一個事務的執行不能被其他事務干擾,即一個事務內部的操作及使用數據對正進行的其他事務是隔離的,併發執行的各個事務之間不能相互干擾。

  1. 持久性

持久性,是指一個事務一旦完成事務,後續的其他操作和故障不會對事務的結果產生任何影響。

什麼是分佈式事務?

分佈式事務就是要在分佈式系統中的實現事務。在分佈式系統中,在保證可用性和不嚴重犧性能的前提下,光是要實現數據的一致性就已經非常困難了,所以出現了很多“殘血版”的一致性,比如順序一致性、最終一致性等等。

CAP 原理

CAP 原理,是指分佈式系統中,Consistency(一致性),Availability(可用性),Partion tolerance(分區容錯性),三者不可兼得。

  1. 一致性(C)

在分佈式系統中所有的數據備份,同一個時刻是同樣的。

  1. 可用性(A)

在集羣中一部分節點故障,集羣整體是否還能響應客戶端的讀寫請求。

  1. 分區容錯性 (P)

以實際效果而言,分區相當於對通訊的實現要求,系統如果不能在時限內達成數據一致性,就意味着發生了分區的情況,必須就當前操作 在 C 和 A 之間做出選擇。

如何實現分佈式事務?

實現分佈式事務有 2PC(TWO-phase Commit 也叫量階段提交),TCC(Try-Confirm-Cancel) 和事務消息。

消息事務機制--異步確保機制

兩階段提交

兩階段提交保障了分佈式事務的原子性:即所有節點要麼全做,要麼全部做,所謂的兩個階段:第一個階段:準備階段;第二階段:提交階段。

兩階段提交

1,準備階段

事務協調者給每個參與者(資源管理器)發送 PrePare 消息,每個參與者要麼直接返回失敗(如權限驗證失敗),要麼在本地執行事務,寫本地的 redo 和 undo 日誌,但是不提交。

  1. 提交階段

如果協調者收到的參與者的失敗消息或者超時,直接給每個參與者發送回滾(Rollback)消息,否則,發送提交(Commit); 參與者根據協調者提交或者回滾操作,釋放所有事物處理過程中的鎖資源。

RocketMQ 中的分佈式事務實現

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

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

舉個例子,訂單系統 根據消息中的訂單ID ,在訂單庫中查詢這個訂單是否存在即可,如果訂單存在則返回成功,否則返回失敗, RocketMQ 會自動根據事務反查的結果提交或者回滾事務。

RocketMQ事務

程序員開發者社區

程序員開發者社區

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章