分散式事務解決方案——柔性事務與服務模式

HollisChuang發表於2018-07-16

在我的部落格中,介紹過很多關於分散式和事務的文章,在閱讀本文之前,希望讀者可以對這些基礎知識有所瞭解,這裡簡單把之前的文章列舉下,已經按照順序排好,可按順序閱讀:

初識分散式系統

關於分散式一致性的探究

分散式系統的CAP理論

分散式系統的BASE理論

Java中的事務——JDBC事務和JTA事務

Java中的事務——全域性事務與本地事務

關於分散式事務、兩階段提交協議、三階提交協議

深入理解分散式系統的2PC和3PC

這裡簡單總結下以前幾篇文章,算是本文的背景知識。在分散式系統中,存在CAP理論,即可用性、資料一致性和分割槽容錯性無法同時滿足。所以,一個基於CAP的最終一致性理論BASE理論是目前解決分散式問題比較靠譜的。

在分散式系統中,是無法使用本地事務保證資料的一致性的。一種標準的分散式事務就是全域性事務(DTP模型)。他是基於2PC來控制的。但是由於2PC自身就存在同步阻塞的問題,這也就導致全域性事務效率很低。所以,這種全域性事務並不適合解決大型網站的分散式事務問題。

柔性事務

在業內,主要用來解決分散式事務的方案是使用柔性事務。所謂柔性事務,相比較與資料庫事務中的ACID這種剛性事務來說,柔性事務保證的事“基本可用,最終一致。”這其實就是基於BASE理論,保證資料的最終一致性。

雖然柔性事務並不像剛性事務那樣完全遵循ACID,但是,也是部分遵循ACID的,簡單看一下關於ACID四個屬性,柔性事務的支撐程度:

原子性:嚴格遵循

一致性:事務完成後的一致性嚴格遵循;事務中的一致性可適當放寬

隔離性:並行事務間不可影響;事務中間結果可見性允許安全放寬

永續性:嚴格遵循

柔性事務的基礎

前面介紹過了柔性事務的定義,目前,在業內,關於柔性事務,最主要的有以下三種型別:非同步確保型、補償型、最大努力通知型。

這三種型別的柔性事務基本都有對應的實現,不同的場景需要使用不同的柔性事務型別。而這幾種柔性事務型別,其實還是依賴一些基礎模式的,或者叫做基礎介面,基礎功能。

比如,要想使用可靠訊息最終一致來實現非同步確保型柔性事務,就依賴接冪等操作和可查詢操作。關於具體實現,我們在後面的文章中介紹,本文簡單介紹下這些實現柔性事務依賴的基礎模式。

注意,下面要介紹的柔性事務的模式,並不是柔性事務的方案。這些是做柔性事務的基礎。也就是說,如果你想做柔性事務,你的介面和功能要滿足下面的幾個要求。不一定要都滿足,因為不同的方案的要求不一樣。但是都不滿足的話,是不可能做柔性事務的。

可查詢操作

可查詢操作,幾乎是所有的分散式解決方案都需要的。

舉一個常見的分散式場景的例子,如訂單處理這一功能:

/** 支付訂單處理 **/
public void completeOrder() {
    orderDao.update(); // 訂單服務本地更新訂單狀態
    accountService.update(); // 呼叫資金賬戶服務給資金帳戶加款
    pointService.update(); // 呼叫積分服務給積分帳戶增加積分
    accountingService.insert(); // 呼叫會計服務向會計系統寫入會計原始憑證
    merchantNotifyService.notify(); // 呼叫商戶通知服務向商戶傳送支付結果通知
}
複製程式碼

以上這個支付訂單處理的例子中,除了訂單服務本地更新訂單狀態以外的所有操作,都需要呼叫RPC介面來執行,這種情況單純的本地事務就無法保證資料的一致性了。就需要引入分散式事務。在分散式事務執行過程中,如果某一個步驟執行出錯,就需要明確的知道其他幾個操作的處理情況,這就需要其他的服務都能夠提供查詢介面,保證可以通過查詢來判斷操作的處理情況。

query

為了保證操作的可查詢,需要對於每一個服務的每一次呼叫都有一個全域性唯一的標識,可以是業務單據號(如訂單號)、也可以是系統分配的操作流水號(如支付記錄流水號)。除此之外,操作的時間資訊也要有完整的記錄。

冪等操作

冪等性,其實是一個數學概念。冪等函式,或冪等方法,是指可以使用相同引數重複執行,並能獲得相同結果的函式,如:

f(f(x)) = f(x)
複製程式碼

在程式設計中一個冪等操作的特點是其任意多次執行所產生的影響均與一次執行的影響相同。也就是說,同一個方法,使用同樣的引數,呼叫多次產生的業務結果與呼叫一次產生的業務結果相同。

mi

這一個要求其實也比較好理解,因為要保證資料的最終一致性,很多解決防範都會有很多重試的操作,如果一個方法不保證冪等,那麼將無法被重試。

冪等操作的實現方式有多種,如在系統中快取所有的請求與處理結果、檢測到重複操作後,直接返回上一次的處理結果等。

可補償操作

提到事務,為了保證原子性,就可能發生commit和rollback,那麼在分散式事務中,要想進行rollback,就需要提供可補償操作。

bu

比如上面的訂單處理的例子中,在呼叫積分服務給積分帳戶增加積分操作執行之後,經過分散式事務協調,最終決定回滾整個事務,那麼就需要提供一個呼叫積分服務給積分帳戶扣減積分的操作。

並且,補償操作同時也需要滿足冪等性。

TCC操作

TCC 即 Try-Confirm-Cancel。

tcc

Try: 嘗試執行業務

完成所有業務檢查(一致性) 預留必須業務資源(準隔離性)

Confirm:確認執行業務

真正執行業務 不作任何業務檢查 只使用Try階段預留的業務資源 Confirm操作要滿足冪等性

Cancel: 取消執行業務

釋放Try階段預留的業務資源
Cancel操作要滿足冪等性

這種型別和可補償操作類似,就是提供一種提交和回滾的機制。是一種典型的兩階段型別的操作。這裡說的兩階段型別操作並不是指2PC,他和2PC還是有區別的。

TCC與2PC協議比較 TCC位於業務服務層而非資源層 TCC沒有單獨的準備(Prepare)階段,Try操作兼備資源操作與準備能力 • Try操作可以靈活選擇業務資源的鎖定粒度(以業務定粒度) TCC有較高開發成本

總結

本文主要是簡單介紹了一下柔性事務和柔性事務實現的基礎。柔性事務是目前主流的分散式事務解決方案,其基礎模式包含四個:冪等操作、可補償操作、可查詢操作和TCC操作。後續文章會分別介紹關於分散式事務的解決方案,敬請期待。

分散式事務解決方案——柔性事務與服務模式

參考資料

大規模SOA系統中的分佈事務處理_程立

相關文章