一. 2PC/XA(兩階段提交)
1.准備階段
協調者詢問參與者是否准備成功,參與者回復結果
2.提交階段
如果事務在每個參與者身上都執行成功了,協調者會發通知讓所有參與者提交事務,否則,協調者讓所有參與者回滾事務
注意:(在准備階段中,參與者執行了事務,但是並沒有提交,只有在提交階段,接受到協調者通知之后,才會進行提交或者回滾)
存在的問題:
1.同步堵塞:所有參與者在等待其他參與者響應的過程中都處於同步堵塞狀態,無法進行其他操作
2.單點問題:協調者在2PC/XA中起到起到非常大的作用,發生故障將會造成很大影響,在第二階段,如果出現問題,會導致所有參與者處於等待狀態,無法進行其他操作
3.數據不一致:在第二階段,如果協調者只發送了部分Commit消息,此時出現了故障,就會導致部分參與者提交事務,其他參與者沒有提交事務,使得數據不一致
4.太過保守:任意節點失敗都會導致整個事務提交失敗,沒有完善的容錯機制
二. TCC(補償事務)
1.采用補償機制,針對每一個操作,都會注冊一個與其對應的確認和補償操作,它分為3個階段
(1)try階段主要是對業務系統進行檢測和資源預留
(2)confirm階段是對業務系統做確認提交,try階段執行成功后開始執行confirm,默認cofirm是不會出錯的,即try成功,confirm一定成功
(3)cancal階段是在業務執行錯誤,需要回滾的狀態下執行的業務取消,預留資源釋放
2.優點:跟2PC比起來,實現以及流程相對簡單一點,但是數據的一致性也比2PC差一點
3.缺點:缺點比較明細,在2,3步都有可能失敗,TCC屬於應用層的補償方式,不是很好處理
三. 本地消息表(異步確保)
1.本地消息表與業務數據表處於同一個數據庫中,這樣就能利用本地事務來保證在對這兩個表的操作滿足事務特性,並且使用了消息隊列保證最終一致性
(1)在分布式事務操作的一方完成寫業務數據的操作之后向本地消息表發送一個消息,本地事務能保證這個消息一定寫入本地消息表中
(2)之后講本地消息表中的消息轉發到kafka等消息隊列里,如果轉發成功則將消息從本地消息表中刪除,否則繼續重新轉發
(3)在分布式事務操作的另一方從消息隊列中讀取到一個消息,並執行消息中的操作
2.優點:一種非常經典的實現,避免了分布式事務,實現了最終一致性
3.消息表會耦合到業務系統中,如果沒有封裝好的解決方案,會有很多雜活需要處理
四. 3PC
1.3PC的出現是為了解決2PC的一些問題,相比於2PC,他在參與者中也引入了超時機制,並且新增一個階段使得參與者可以利用這個階段統一各自的狀態
3PC包含3個階段,准備階段,預提交階段,提交階段
3PC的准備階段協調者只會詢問參與者的自身情況,而預提交階段就是和2PC的准備階段一樣,除了事務的提交其他該做的都做好了,提交階段就是和2PC一樣
不管哪個階段有參與者返回失敗都會宣布事務失敗,和2PC一樣
2. 3PC的階段影響
(1)准備階段的變更不會直接影響事務,而是去詢問參與者是否有條件接這個事務,因此不會鎖資源,不會使在某些資源不可用的情況下 所有參與者都堵塞
(2)預提交階段的引入起到了統一狀態的作用,但是多引入了一個階段也就多了一層交互,會導致性能差點,而且絕大部分的情況下資源都應該是可用的
3. 參與者超時帶來的影響
(1)2PC是同步堵塞的,而3PC引入了超時機制,如果等待提交命令的時候超時了,參與者就會提交事務,到了這個階段大概率是提交,如果等待預提交命令超時,那就該干啥干啥
(2)超時機制也會帶來數據不一致的問題,比如在等待提交命令超時了,參與者默認執行的是提交事務,但是有可能執行回滾操作,這樣就會導致數據不一致
4. 引入了參與者超時機制,並且增加了預提交階段使得故障恢復之后協調者的決策復雜度降低,但整體的交互過程更長了,性能有所下降,並且還是會存在數據不一致問題。
五. MQ消息事務
1.通過消息實現事務過程
(1)先給Broker發送事務消息即半消息(對消費者來說不可見,然后發送成功后發送方再執行本地事務)
(2)再根據本地事務的結果向Broker發送Commit或者RollBack命令
(3)並且RocketMQ的發送方會提供一個反查事務狀態接口,如果一段時間內辦消息沒有收到任何操作請求,那么Broker會通過反查接口得知發送方事務是否執行成功,然后執行Commit或者RollBack命令
(4)如果是Commit那么訂閱方就能收到這個消息,然后在做對應的操作,做完之后再消費這條消息
(5)如果是RollBack那么訂閱方收不到這條消息,等於事務沒執行過
六. 最大努力通知
最大努力通知其實表明了一種柔性事務的思想
總結:
可以看出 2PC 和 3PC 是一種強一致性事務,不過還是有數據不一致,阻塞等風險,而且只能用在數據庫層面。
而 TCC 是一種補償性事務思想,適用的范圍更廣,在業務層面實現,因此對業務的侵入性較大,每一個操作都需要實現對應的三個方法。
本地消息、事務消息和最大努力通知其實都是最終一致性事務,因此適用於一些對時間不敏感的業務