天天看點

分布式事務開山之作——《深入了解分布式事務:原理與實戰》草圖曝光!!

大家好,我是冰河~~

今天,咱們就暫時不聊【精通高并發系列】了,今天插播一下分布式事務,為啥?因為冰河聯合貓大人共同創作的分布式事務領域的開山之作——《深入了解分布式事務:原理與實戰》一書正式出版了,于2021年10月20日開始在當當預售,當天即登上當當新書榜第一的位置!

劃重點:當當10.20~10.24限時5折優惠!!打開當當首頁,搜尋:分布式事務,找到5折優惠商品連結,點選加購,下單即可。

分布式事務開山之作——《深入了解分布式事務:原理與實戰》草圖曝光!!

本地事務

本地事務流程

在介紹分布式事務之前,我們先來看看本地事務。首先,我們先來一張圖。

分布式事務開山之作——《深入了解分布式事務:原理與實戰》草圖曝光!!

由上圖,我們可以看出,本地事務由資料總管(比如DBMS,資料庫管理系統)在本地進行管理。

本地事務的優缺點

本地事務具備相應的優點,也有其不足。

優點:

  • 支援嚴格的ACID屬性。
  • 可靠,事務實作的效率高(隻是在本地操作)。
  • 可以隻在RM(資料總管)中操作事務。
  • 程式設計模型簡單。

缺點:

  • 缺乏分布式事務的處理能力。
  • 資料隔離的最小單元由RM(資料總管決定),開發人員無法決定資料隔離的最小單元。比如:資料庫中的一條記錄等。

ACID屬性

說起事務,我們不得不提的就是事務的ACID屬性。

分布式事務開山之作——《深入了解分布式事務:原理與實戰》草圖曝光!!
  • A(Atomic):原子性,構成事務的所有操作,要麼都執行完成,要麼全部不執行,不可能出現部分成功部分失

    敗的情況。

  • C(Consistency):一緻性,在事務執行前後,資料庫的一緻性限制沒有被破壞。比如:張三向李四轉100元,

    轉賬前和轉賬後的資料的正确狀态叫作一緻性,如果出現張三轉出100元,李四賬戶沒有增加100元這就出現了數

    據錯誤,就沒有達到一緻性。

  • I(Isolation):隔離性,資料庫中的事務一般都是并發的,隔離性是指并發的兩個事務的執行互不幹擾,一個事

    務不能看到其他事務運作過程的中間狀态。通過配置事務隔離級别可以避髒讀、重複讀等問題。

  • D(Durability):持久性,事務完成之後,該事務對資料的更改會被持久化到資料庫,且不會被復原。

分布式事務

随着業務的快速發展,網站系統往往由單體架構逐漸演變為分布式、微服務架構,而對于資料庫則由單機資料庫架構向分布式資料庫架構轉變。此時,我們會将一個大的應用系統拆分為多個可以獨立部署的應用服務,需要各個服務之間進行遠端協作才能完成事務操作。

我們可以使用下圖來表示剛開始我們系統的單體架構。

分布式事務開山之作——《深入了解分布式事務:原理與實戰》草圖曝光!!

上圖中,我們将同一個項目中的不同子產品組織成不同的包來進行管理,所有的程式代碼仍然是放在同一個項目中。

後續由于業務的發展,我們将其擴充為分布式、微服務架構。此時,我們将一個大的項目拆分為一個個小的可以獨立部署的微服務,每個微服務都有自己的資料庫,如下所示。

分布式事務開山之作——《深入了解分布式事務:原理與實戰》草圖曝光!!

又比如,在我們的程式中,經常會在同一個事務中執行類似如下的代碼來完成我們的需求。

@Transactional(rollbackFor = Exception.class)
public void submitOrder() {
    orderDao.update(); // 更新訂單資訊
    accountService.update(); // 修改資金賬戶的金額
    pointService.update(); //  修改積分
    accountingService.insert(); // 插入交易流水
    merchantNotifyService.notify(); // 通知支付結果
}
           

上述代碼中的業務,僅僅在submitOrder()方法上添加了一個@Transactional注解,這能夠在分布式場景下避免分布式事務的問題嗎?很顯然是不行的。

如果上述代碼所對應的:訂單資訊、資金賬戶資訊、積分資訊、交易流水等資訊分别存儲在不同的資料裡,而支付完成後,通知的目标系統的資料同樣是存儲在不同的資料庫中。此時就會産生分布式事務問題。

分布式事務産生的場景

跨JVM程序

當我們将單體項目拆分為分布式、微服務項目之後,各個服務之間通過遠端REST或者RPC調用來協同完成業務操作。典型的場景就是:商城系統中的訂單微服務和庫存微服務,使用者在下單時會通路訂單微服務,訂單微服務在生成訂單記錄時,會調用庫存微服務來扣減庫存。各個微服務是部署在不同的JVM程序中的,此時,就會産生因跨JVM程序而導緻的分布式事務問題。

分布式事務開山之作——《深入了解分布式事務:原理與實戰》草圖曝光!!

跨資料庫執行個體

單體系統通路多個資料庫執行個體,也就是跨資料源通路時會産生分布式事務。例如,我們的系統中的訂單資料庫和交易資料庫是放在不同的資料庫執行個體中,當使用者發起退款時,會同時操作使用者的訂單資料庫和交易資料庫,在交易資料庫中執行退款操作,在訂單資料庫中将訂單的狀态變更為已退款。由于資料分布在不同的資料庫執行個體,需要通過不同的資料庫連接配接會話來操作資料庫中的資料,此時,就産生了分布式事務。

分布式事務開山之作——《深入了解分布式事務:原理與實戰》草圖曝光!!

多服務單資料庫

多個微服務通路同一個資料庫。例如,訂單微服務和庫存微服務通路同一個資料庫也會産生分布式事務,原因是:多個微服務通路同一個資料庫,本質上也是通過不同的資料庫會話來操作資料庫,此時就會産生分布式事務。

分布式事務開山之作——《深入了解分布式事務:原理與實戰》草圖曝光!!

注意:跨資料庫執行個體場景和多服務單資料庫場景,本質上都是因為會産生不同的資料庫會話來操作資料庫中的資料,進而産生分布式事務。這兩種場景是大家比較容易忽略的。

分布式事務解決方案

知道了分布式事務産生的場景後,接下來,我們就聊聊分布式事務具體有哪些解決方案。

2PC方案

2PC即兩階段送出協定,是将整個事務流程分為兩個階段,準備階段(Prepare phase)、送出階段(commit

phase),2是指兩個階段,P是指準備階段,C是指送出階段。

這裡,我們用MySQL資料庫舉例,MySQL資料庫支援兩階段送出協定,可以分為成功和失敗兩種情況。

成功情況

分布式事務開山之作——《深入了解分布式事務:原理與實戰》草圖曝光!!

失敗情況

分布式事務開山之作——《深入了解分布式事務:原理與實戰》草圖曝光!!

具體流程如下:

準備階段(Prepare phase): 事務管理器給每個參與者發送Prepare消息,每個資料庫參與者在本地執行事

務,并寫本地的Undo/Redo日志,此時事務沒有送出。

(Undo日志是記錄修改前的資料,用于資料庫復原,Redo日志是記錄修改後的資料,用于送出事務後寫入數

據檔案)

送出階段(commit phase): 如果事務管理器收到了參與者的執行失敗或者逾時消息時,直接給每個參與者

發送復原(Rollback)消息;否則,發送送出(Commit)消息;參與者根據事務管理器的指令執行送出或者復原操

作,并釋放事務處理過程中使用的鎖資源。

使用2PC方案時,需要注意的是:必須在最後階段釋放鎖資源。

可靠消息最終一緻性方案

可靠消息最終一緻性方案是指當事務發起方執行完成本地事務後并發出一條消息,事務參與方(消息消費者)一定能

夠接收消息并處理事務成功,此方案強調的是隻要消息發給事務參與方最終事務要達到一緻。

分布式事務開山之作——《深入了解分布式事務:原理與實戰》草圖曝光!!

事務發起方(消息生産方)将消息發給消息中間件,事務參與方從消息中間件接收消息,事務發起方和消息中間件

之間,事務參與方(消息消費方)和消息中間件之間都是通過網絡通信,由于網絡通信的不确定性會導緻分布式事

務問題。 是以,我們在具體方案中會引入消息确認服務和消息恢複服務。

使用可靠消息最終一緻性方案時需要注意幾個問題:

  • 本地事務與消息發送的原子性問題。
  • 事務參與方接收消息的可靠性問題。
  • 消息重複消費的問題(需要實作幂等)。

TCC方案

TCC分為三個階段:

  • Try 階段 是做業務檢查(一緻性)及資源預留(隔離),此階段僅是一個初步操作,它和後續的Confirm 一起才能

    真正構成一個完整的業務邏輯。

  • Confirm 階段 是做确認送出,Try階段所有分支事務執行成功後開始執行 Confirm。通常情況下,采用TCC則

    認為 Confirm階段是不會出錯的。即:隻要Try成功,Confirm一定成功。若Confirm階段真的出錯了,需引

    入重試機制或人工處理。

  • Cancel 階段 是在業務執行錯誤需要復原的狀态下執行分支事務的業務取消,預留資源釋放。通常情況下,采

    用TCC則認為Cancel階段也是一定成功的。若Cancel階段真的出錯了,需引入重試機制或人工處理。

分布式事務開山之作——《深入了解分布式事務:原理與實戰》草圖曝光!!

使用TCC分布式解決方案時需要注意空復原、幂等、懸挂等問題。

最大努力通知型方案

此種方案主要用于多個不同系統之前保證資料的最終一緻性,大體如下圖所示。

分布式事務開山之作——《深入了解分布式事務:原理與實戰》草圖曝光!!

使用最大努力通知型方案需要注意幂等和資料的回查操作。

寫在最後

為了讓小夥伴們更好的了解本書,在文章最後冰河附上幾張精美的圖檔。

分布式事務開山之作——《深入了解分布式事務:原理與實戰》草圖曝光!!
分布式事務開山之作——《深入了解分布式事務:原理與實戰》草圖曝光!!
分布式事務開山之作——《深入了解分布式事務:原理與實戰》草圖曝光!!
分布式事務開山之作——《深入了解分布式事務:原理與實戰》草圖曝光!!
分布式事務開山之作——《深入了解分布式事務:原理與實戰》草圖曝光!!
分布式事務開山之作——《深入了解分布式事務:原理與實戰》草圖曝光!!
分布式事務開山之作——《深入了解分布式事務:原理與實戰》草圖曝光!!
分布式事務開山之作——《深入了解分布式事務:原理與實戰》草圖曝光!!

哈哈,喜歡的小夥伴當當下單即可,有啥問題可以私信冰河咨詢,冰河看到後都會一一解答。

好了,今天就到這兒吧,我是冰河,我們下期見~~