-
總述 -
咱們前面分别對分布式事務的幾個分支:XA、2PC、3PC、TCC、Saga、事務消息、最大努力事務進行的詳細介紹。本篇作為分布式事務設計的收尾篇,講對前面的内容查缺補漏和總結,最後對市面的一些開源架構做一些介紹。
- 查缺補漏 -
-
補償型事務
柔性事務分補償型事務和通知型事務。但對補償型事務沒有進行詳細介紹,那什麼是補償型事務呢,在Atomikos 公司Guy Pardon的論文《Business_Activities》中有這樣的描述: 大緻含義是,"補償是一個獨立的支援ACID特性的本地事務,用于在邏輯上取消了先前ACID互動的影響。對于一個長事務來說,基于補償的方法可将事務資源鎖定時間保持在最低程度,進而避免了事務資源長期占用等缺點。”。
2.TCC事務模型補充
咱們前面文章說了不推薦TCC,并且認為Seata的AT模式從理論上來說更像是Saga的變種,而非TCC的變種。目前有很多資料自行将TCC分了幾個分支:
通用型TCC:标準TCC模型實作,從業務服務需要提供try、confirm、cancel
補償性TCC:子服務隻需要提供 Do 和 Compensate 兩個接口
異步確定型 TCC:主服務是可靠消息服務,而子服務則通過消息服務解耦,作為消息服務的消費端,異步地執行。可靠消息服務需要提供 Try、Confirm、Cancel 三個接口。Try 接口隻負責持久化記錄存儲消息資料;Confirm 接口确認發送,這時才開始真正的投遞消息;Cancel 接口取消發送,删除消息資料。
原始論文《Life beyond Distributed Transactions》和 Atomikos 官網上并沒有類似的劃分,這些劃分其實是一些公司在内部實踐中,自行提出的概念。但是并未找到比較大的公司進行背書。是以其實咱們從論文上去看:
補償性TCC并未提供Try接口,其實已經更接近Saga了,反而應該認為是Saga的變種。
異步確定型 TCC中 子服務不需要提供try、confirm、cancel三個接口,稱為TCC貌似也不合适,從本質上其實事務消息的一種可靠投遞方式而已。
-
Saga 事務模型補充
咱們說過Saga設計必須遵循允許空補償、保持幂等性、防止資源懸挂三個政策,因為Saga事務不保證隔離性,在極端情況下可能由于髒寫無法完成復原操作。比如舉一個極端的例子, 分布式事務内先給使用者A充值, 然後給使用者B扣減餘額, 如果在給A使用者充值成功, 在事務送出以前, A使用者把餘額消費掉了, 如果事務發生復原, 這時則沒有辦法進行補償了。這就是缺乏隔離性造成的典型的問題, 實踐中一般的應對方法是:
業務流程設計時遵循“甯可長款, 不可短款”的原則, 長款意思是客戶少了錢機構多了錢, 以機構信譽可以給客戶退款, 反之則是短款, 少的錢可能追不回來了。是以在業務流程設計上一定是先扣款。
有些業務場景可以允許讓業務最終成功, 在復原不了的情況下可以繼續重試完成後面的流程, 是以要求Saga除了提供“復原”能力還需要提供“向前”恢複上下文繼續執行的能力, 讓業務最終執行成功, 達到最終一緻性的目的。
Saga 實作分兩種,一種是Saga 狀态機實作,一種是Saga AOP Proxy實作,但是前文缺少對比,補充如下:

Saga 狀态機實作,在關于參與者服務編排實作又有集中式和協同式兩種分支,他們的對比詳情如下:
-
TCC VS Saga
補償型事務事務主要分TCC 和 Saga。咱們前文中說到Saga 沒有Try行為,直接commit,是以會留下原始事務操作痕迹。TCC Cancel是完美補償的Rollback,補償操作會徹底清理之前的原始事務操作,使用者是感覺不到事務取消之前的狀态資訊的。最近回看文章時,發現比較多人對此有疑問,是以進行補充诠釋下:
從業務流程上說,TCC的Try行為是嘗試階段, Comfirm 和Cannel是确認/復原。是兩階段的廣義實作,在頁面表現上可以使用定時回查結果,那麼對客戶的說就是完美補償行為。而Saga直接commit,在業務流程上存在的客戶感官上的髒讀現象。
在資料層面上來說,TCC利用了資料的中間态,Cannel針對中間台資料進行復原,進而不存在資料污染問題;而Saga使用的是反向操作,存在資料變化記錄影響,有資料污染嫌疑。
TCC 和Saga 的對比 補充一個适用場景的相關對比資訊:
TCC 适用于執行時間确定且較短、對一緻性要求比較高、資料隔離強的業務,比如支付場景。
Saga 适用于業務流程長、業務流程多的業務,在銀行業金融機構使用廣泛。比如網際網路微貸、管道整合場景
-
總結 -
單資料庫事務可以滿足事務ACID 四個特性,提供強一緻性保證,但在分布式事務要完全遵循 ACID 特性會比較困難。在網際網路時代中,我們通常追求分布式系統的高可用和高吞吐,是以分布式事務一般選擇最終一緻性。
咱們把提供強一緻性的事務稱之為剛性事務,把提供最終一緻性的事務稱之為柔性事務。剛性事務可以完全滿足 ACID 四個特性,柔性事務對事務的 ACID 特性的支援情況如下:
原子性:完全支援。
一緻性:隻提供最終一緻性支援。
隔離性:不完全保證,通常為了系統的吞吐和性能,會一定程度上放棄對隔離性的要求。
持久性:完全支援。
在分布式系統中,CAP理論通常是指導思維,而BASE理論是CAP理論中的AP延申,是對 CAP 中的一緻性和可用性進行一個權衡的結果,理論的核心思想就是:我們無法做到強一緻,但每個應用都可以根據自身的業務特點,采用适當的方式來使系統達到最終一緻性。而柔性事務其實就是BASE理論的實踐産物。因為分布式事務難免會對系統造成一定的性能損耗,是以在網際網路高可用和高吞吐的要求下。我們通常處理分布式事務的原則是:業務規避 > BASE柔性事務 > CP剛性事務。柔性事務通常推薦 同步Saga、異步事務消息;剛性事務推薦 2PC實作。
-
開源架構推薦 -
從結論上我們可以看出業務規避其實已經沒有了分布式事務的必要性,是以如果實在無法業務規避或者規避成本更加昂貴下,我們必須有分布式事務來處理資料一緻性問題。這時我們需要選擇一個合适的分布式架構來處理事務。我對業界常見分布式事務做了一定比較,其實有大廠背景背書、經過大量生産實踐、開源元件的隻有華為的ServiceComb Saga、阿裡的Seata、Apache Camel Saga。但是華為ServiceComb Saga和 Apache Camel Saga隻提供了Saga實作,而阿裡Seata提供了AT、Saga、XA(剛出不久,不建議馬上使用)。從廣度上來說,其實Seata是占比較大的優勢,我剛好對Seata又有比較深的研究,是以強烈推薦Seata。
本文來源于:奈學開發者社群,如有侵權請聯系我删除!