微服務分散式事務元件 Seata(一)

HuDu發表於2022-08-11

前言

事務簡介

事務(Transaction)是訪問並可能更新資料庫中各種資料項的一個程式執行單元(unit)。 在關聯式資料庫中,一個事務由一組SQL語句組成。 事務應該具有4個屬性:原子性、一致性、隔離性、永續性。這四個屬性通常稱為ACID特性。
  • 原子性(atomicity):事務是一個不可分割的工作單位, 事務中包括的諸操作要麼都做,要麼都不做。
  • 一致性(consistency):事務必須是使資料庫從一個一致性狀態變到另一 個一 致性狀態, 事務的中間狀態不能被觀察到的。
  • 隔離性(isolation) : 一個事務的執行不能被其他事務干擾。即一個事務內部的操作及使用的資料對併發的其他事務是隔離的,併發執行的各個事務之間不能互相干擾。隔離性又分為四個級別:讀未提交(read uncommitted)、讀已提交(read committed,解決髒讀)、可重複讀(repeatable read,解決虛讀)、序列化(serializable,解決幻讀)。
  • 永續性(durability) :永續性也稱永久性(permanence) ,指一個事務一旦提交, 它對資料庫中資料的改變就應該是永久性的。接下來的其他操作或故障不應該對其有任何影響。任何事務機制在實現時,都應該考慮事務的ACID特性,包括:本地事務、分散式事務,及時不能都很好的滿足,也要考慮支援到什麼程度。

本地事務

@Transactional,大多場景下,我們的應用都只需要操作單一的資料庫,這種情況下的事務稱之為本地事務(Local Transaction),本地事務的 ACID 特性是資料庫直接提供支援。本地事務應用架構如下

微服務分散式事務元件 Seata

在 JDBC 程式設計中,我們透過java.sql.Connection物件來開啟、關閉或者提交事務

Connection conn = ... // 獲取資料庫連線
conn.setAutoCommit(false);// 關閉自動提交
try{
  // ... 執行增刪改查 sql
  conn.commit(); // 提交事務
} catch(Exception e) {
  conn.rollback(); // 事務回滾
} finally {
  conn.close(); //關閉連線
}

分散式事務

下面兩種情況如果是按照之前的本地事務,是無法保證事務的。

微服務分散式事務元件 Seata

微服務分散式事務元件 Seata

一、什麼是 Seata

Seata是一款開源的分散式事務解決方案, 致力於提供高效能和簡單易用的分散式事務服務。Seata 將為使用者提供了ATTCCSAGAXA 事務模式,為使用者打造一站式的分散式解決方案。AT 模式是阿里首推的模式,阿里雲上有商用版本的 GTS (Global Transaction Service全域性事務服務)

常見的分散式事務解決方案

  1. seata 阿里分散式事務框架
  2. 訊息佇列
  3. SAGA
  4. XA

他們有一個共同點,都是“兩階段(2PC)”。“兩階段”是指完成整個分 布式事務,劃分成兩個步驟完成。
實際上,這四種常見的分散式事務解決方案,分別對應著分散式事務的四種模式: AT、 TCC、 Saga、 XA;

2PC兩階段提交(Two-Phase Commit)協議:
顧名思義,分為兩個階段:Prepare 和 Commit

1.1、Prepare:提交事務請求

基本流程如下

微服務分散式事務元件 Seata

微服務分散式事務元件 Seata

  1. 詢問協調者向所有參與者傳送事務請求,詢問是否可執行事務操作,然後等待各個參與者的響應。
  2. 執行各個參與者接收到協調者事務請求後,執行事務操作(例如更新一個關 系型資料庫表中的記錄),並將 Undo 和 Redo 資訊記錄事務日誌中。
  3. 響應如果參與者成功執行了事務並寫入Undo和Redo資訊,則向協調者返回YES響應,否則返回NO響應。當然,參與者也可能當機,從而不會返回響應。

1.2、正常提交事務

微服務分散式事務元件 Seata

微服務分散式事務元件 Seata

  1. commit請求協調者向所有參與者傳送Commit請求。
  2. 事務提交參與者收到 Commit 請求後,執行事務提交,提交完成後釋放事務執行期佔用的所有資源。
  3. 反饋結果參與者執行事務提交後向協調者傳送Ack響應。
  4. 完成事務接收到所有參與者的Ack響應後,完成事務提交。

1.3、中斷事務

在執行Prepare步驟過程中,如果某些參與者執行事務失敗、當機或與協調者之間的網路中斷,那麼協調者就無法收到所有參與者的 YES 響應,或者某個參與者返回了 No 響應,此時,協調者就會進入回退流程,對事務進行回退。流程如下圖紅色部分(將Commit請求替換為紅色的Rollback 請求)

微服務分散式事務元件 Seata

  1. rollback請求協調者向所有參與者傳送Rollback請求。
  2. 事務回滾參與者收到Rollback後,使用Prepare階段的Undo日誌執行事務回滾,完成後釋放事務執行期佔用的所有資源。
  3. 反饋結果參與者執行事務回滾後向協調者傳送 Ack 響應。
  4. 中斷事務接收到所有參與者的Ack響應後,完成事務中斷。

二、2PC 的問題

  1. 同步阻塞參與者在等待協調者的指令時,其實是在等待其他參與者的響應,在此過程中,參與者是無法進行其他操作的,也就是阻塞了其執行。倘若參 與者與協調者之間網路異常導致參與者一直收不到協調者資訊,那麼會導致參與者一直阻塞下去。
  2. 單點在2PC中,一切請求都來自協調者,所以協調者的地位是至關重要的,如果協調者當機,那麼就會使參與者一直阻塞並一直佔用事務資源。如果協調者也是分散式,使用選主方式提供服務,那麼在一個協調者掛掉後, 可以選取另一個協調者繼續後續的服務,可以解決單點問題。但是,新協調者無法知道上一個事務的全部狀態資訊(例如已等待Prepare響應的時長等),所以也無法順利處理上一個事務。
  3. 資料不一致Commit事務過程中Commit請求/Rollback請求可能因為協調者當機或協調者與參與者網路問題丟失,那麼就導致了部分參與者沒有收到Commit/Rollback請求,而其他參與者則正常收到執行了CommitRollback操作,沒有收到請求的參與者則繼續阻塞。這時,參與者之間的資料就不再一 致了。當參與者執行CommitRollback後會向協調者傳送Ack,然而協調者不論是否收到所有的參與者的Ack,該事務也不會再有其他補救措施了,協調者能做的也就是等待超時後像事務發起者返回一個“我不確定該事務是否成功”。
  4. 環境可靠性依賴協調者Prepare請求發出後,等待響應,然而如果有參與者當機或與協調者之間的網路中斷,都會導致協調者無法收到所有參與者的響應,那麼在 2PC 中,協調者會等待一定時間, 然後超時後,會觸發事務中斷,在這個過程中,協調者和所有其他參與者都是出於阻塞的。這種機制對網路問題常見的現實環境來說太苛刻了。

三、AT 模式(auto transaction)

AT模式是一種無侵入的分散式事務解決方案。
阿里seata框架,實現了該模式。
在AT模式下,使用者只需關注自己的“業務SQL”,使用者的“業務SQL”作為一階段, Seata 框架會自動生成務的二階段提交和回滾操作。

微服務分散式事務元件 Seata

  • 一階段

在一階段,Seata 會攔截“業務SQL”,首先解析 SQL 語義,找到“業務 SQL”要更新的業務資料,在業務資料被更新前,將其儲存成“before image”,然後執行“業務SQL”更新業務資料,在業務資料更新之後,再將其儲存成”after image”,最後生成行鎖。以上操作全部在一個資料庫事務內完成, 這樣保證了一階段操作的原子性。

微服務分散式事務元件 Seata

  • 二階段提交

二階段如果是提交的話,因為“業務SQL”在一階段已經提交至資料庫,所以 Seata 框架只需將一階段儲存的快照資料和行鎖刪掉,完成資料清理即可。

微服務分散式事務元件 Seata

  • 二階段回滾

二階段如果是回滾的話,Seata 就需要回滾一階段已經執行的“業務SQL”,還原業務資料。回滾方式便是用“before image”還原業務資料;但在還原前要首先要校驗髒寫,對比“資料庫當前業務資料”和“after image”,如果兩份資料完全一致就說明沒有髒寫, 可以還原業務資料,如果不一致就說明有髒寫,出現髒寫就需要轉人工處理。

微服務分散式事務元件 Seata

四、TCC 模式

TCC 模式需要使用者根據自己的業務場景實現 Try、Confirm 和 Cancel 三個操作;事務發起方在一階段執行 Try 方式,在二階段提交執行 Confim 方法,二階段回滾執行 Cancel 方法。

缺點:
侵入性強,並且得自己實現相關事務控制邏輯
優點:
在整個過程中基本沒有鎖,效能更強

微服務分散式事務元件 Seata

微服務分散式事務元件 Seata

五、基於訊息佇列實現分散式事務

微服務分散式事務元件 Seata

六、Seata 詳細說明

在Seata的架構中,一共有三個角色:
TC (Transaction Coordinator) - 事務協調者
維護全域性和分支事務的狀態,驅動全域性事務提交或回滾。
TM (Transaction Manager) - 事務管理器
定義全域性事務的範圍:開始全域性事務、提交或回滾全域性事務。
RM (Resource Manager) - 資源管理器
管理分支事務處理的資源,與TC交談以註冊分支事務和報告分支事務的狀態,並驅動分支事務提交或回滾。
其中,TC為單獨部署的Server服務端,TM和RM為嵌入到應用中的Client客戶端。

在 Seata 中,一個分散式事務的生命週期如下

微服務分散式事務元件 Seata

1.TM 請求 TC 開啟一個全域性事務。TC 會生成一個 XID 作為該全域性事務的編號。XID 會在微服務的呼叫鏈路中傳播,保證將多個微服務的子事務關聯在一起。
2.RM 請求 TC 將本地事務註冊為全域性事務的分支事務,透過全域性事務的XID進行關聯。
3.TM 請求 TC 告訴 XID 對應的全域性事務是進行提交還是回滾。
4.TC 驅動 RM 們將 XID 對應的自己的本地事務進行提交還是回滾。

本作品採用《CC 協議》,轉載必須註明作者和本文連結

相關文章