天天看點

Distributed transactions in Spring, without XA # Best Efforts 1PC pattern

簡述

Distributed transactions in Spring, with and without XA一文中描述了在Spring中實作分布式事務的7種處理模式;3種基于XA協定,4種特定場景的非XA協定的模式;

最大努力一階段送出模式

4種非XA協定模式的第一種是共享事務資源模式(Shared Transaction Resource pattern),其提供了特定場景的多資源事務同步模式;

第二種便是本文要說的最大努力一階段送出送出模式,在共享事務資源模式中,将兩個系統的事務使用同一個事務資源的一個事務來管理,進而達到一起成功一起失敗的目的;

而在最大努力一階段送出模式中,不特意控制兩個資源在同一個事務中,而是寄希望于其中一個資源的事務管理相當簡單,簡單到唯一肯能發生錯誤的就是基礎組建發生錯誤,而非業務處理錯誤。

比如說關系型資料庫就不是一個這樣的資源,他除了基礎組建會發生錯誤以外,業務上還會發生各種各樣的錯誤情況,比如說主鍵重複,查不到資料時抛出業務異常等等;

從消息系統裡接收消息,就是一個符合這種情況的資源,從其接收到消息之後,業務處理成功之後,送出消息事務,在這裡,接收消息和送出消息事務這兩個操作沒有業務邏輯,隻有像消息伺服器,網絡這種基礎元件出問題時,才有可能出問題。

舉個例子

在這種情況下,如果我們就直接不管消息系統的送出結果,會怎麼樣?還是消息驅動的單個資料庫更新場景,如果不控制消息系統接收消息的事務,隻控制複雜的資料庫事務,那麼處理過程如下:

開啟消息事務
接受消息
開啟資料庫事務
更新資料庫
送出資料庫事務
送出消息事務      

如果是開啟消息事務或者接收消息,這兩個步驟出問題,隻可能是基礎元件的問題,基礎元件恢複之後,重新擷取即可,對整個系統沒有任何影響

如果開啟資料庫事務、更新資料庫或者送出資料庫事務出問題,事務復原,沒有送出消息事務,逾時之後,消息會被重新接收

如果是送出消息事務出問題,這時資料庫事務已經送出,但是消息事務送出失敗,事務逾時時候,消息伺服器會将消息重新發送過來;這時,唯一的一個問題來了,同一個消息會被重新處理一遍。解決這個問題的殺手锏就是保證業務服務的幂等,這個做起來非常容易。

跟Kafka有什麼關系

參考