日韩无码专区无码一级三级片|91人人爱网站中日韩无码电影|厨房大战丰满熟妇|AV高清无码在线免费观看|另类AV日韩少妇熟女|中文日本大黄一级黄色片|色情在线视频免费|亚洲成人特黄a片|黄片wwwav色图欧美|欧亚乱色一区二区三区

RELATEED CONSULTING
相關咨詢
選擇下列產品馬上在線溝通
服務時間:8:30-17:00
你可能遇到了下面的問題
關閉右側工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營銷解決方案
分布式事務(Seata)四大模式詳解

前言

在上一節(jié)中我們講解了,關于分布式事務和seata的基本介紹和使用,感興趣的小伙伴可以回顧一下??《別再說你不知道分布式事務了!》?? 最后小農也說了,下期會帶給大家關于Seata中關于seata中AT、TCC、SAGA 和 XA 模式的介紹和使用,今天就來講解關于Seata中分布式四種模型的介紹。

創(chuàng)新互聯(lián)建站是一家專注于成都網(wǎng)站制作、成都網(wǎng)站設計與策劃設計,沁水網(wǎng)站建設哪家好?創(chuàng)新互聯(lián)建站做網(wǎng)站,專注于網(wǎng)站建設十載,網(wǎng)設計領域的專業(yè)建站公司;建站業(yè)務涵蓋:沁水等地區(qū)。沁水做網(wǎng)站價格咨詢:18980820575

Seata分為三大模塊,分別是 TM、RM 和 TC。

TC (Transaction Coordinator) - 事務協(xié)調者:維護全局和分支事務的狀態(tài),驅動全局事務提交或回滾。

TM (Transaction Manager) - 事務管理器:定義全局事務的范圍:開始全局事務、提交或回滾全局事務。

RM (Resource Manager) - 資源管理器:管理分支事務處理的資源,與TC交談以注冊分支事務和報告分支事務的狀態(tài),并驅動分支事務提交或回滾。

在 Seata 中,分布式事務的執(zhí)行流程:

  • TM 開啟分布式事務(TM 向 TC 注冊全局事務記錄)。
  • 按業(yè)務場景,編排數(shù)據(jù)庫、服務等事務內資源(RM 向 TC 匯報資源準備狀態(tài) )。
  • TM 結束分布式事務,事務一階段結束(TM 通知 TC 提交/回滾分布式事務)。
  • TC 匯總事務信息,決定分布式事務是提交還是回滾。
  • TC 通知所有 RM 提交/回滾 資源,事務二階段結束。

TM 和 RM 是作為 Seata 的客戶端與業(yè)務系統(tǒng)集成在一起,TC 作為 Seata 的服務端獨立部署。

服務端存儲模式支持三種:

file: 單機模式,全局事務會話信息內存中讀寫并持久化本地文件root.data,性能較高(默認)。

DB:  高可用模式,全局事務會話信息通過DB共享,相對性能差一些。

redis: Seata-Server1.3及以上版本支持,性能較高,存在事務信息丟失風險,需要配合實際場景使用。

TC環(huán)境搭建詳解

這里我們使用DB高可用模式,找到conf/file.conf文件。

修改以上中的信息,找到對應的db配置,修改其中的jdbc連接,要注意其中涉及到三個表(global_table,branch_table,lock_table),同時 mysql5和mysql8的驅動是不一樣的。

mysql5:com.mysql.jdbc.Driver。

mysql8:com.mysql.cj.jdbc.Driver。

建表語句地址:https://github.com/seata/seata/blob/develop/script/server/db/mysql.sql。

global_table: 全局事務表,每當有一個全局事務發(fā)起后,就會在該表中記錄全局事務的ID。

branch_table: 分支事務表,記錄每一個分支事務的 ID,分支事務操作的哪個數(shù)據(jù)庫等信息。

lock_table: 全局鎖。

當上述配置好以后,重啟Seata即可生效。

Seata 配置 Nacos

Seata支持注冊服務到Nacos,以及支持Seata所有配置放到Nacos配置中心,在Nacos中統(tǒng)一維護;在 高可用模式下就需要配合Nacos來完成

首先找到 conf/registry.conf,修改registry信息。

registry {
# file 、nacos 、eureka、redis、zk、consul、etcd3、sofa
type = "nacos"
nacos {
application = "seata-server" # 這里的配置要和客戶端保持一致
serverAddr = "127.0.0.1:8848"
group = "SEATA_GROUP" # 這里的配置要和客戶端保持一致
namespace = ""
cluster = "default"
username = "nacos"
password = "nacos"
}
config {
# file、nacos 、apollo、zk、consul、etcd3
type = "nacos"
nacos {
serverAddr = "127.0.0.1:8848"
namespace = ""
group = "SEATA_GROUP"
username = "nacos"
password = "nacos"
dataId = "seataServer.properties"
}
......
}

修改好后,將seata中的一些配置上傳到Nacos中,因為配置項比較多,所以官方提供了一個config.txt,只下載并且修改其中某些參數(shù)后,上傳到Nacos中即可。

下載地址:https://github.com/seata/seata/tree/develop/script/config-center。

修改項如下:

service.vgroupMapping.mygroup=default # 事務分組
store.mode=db
store.db.driverClassName=com.mysql.cj.jdbc.Driver
store.db.url=jdbc:mysql://127.0.0.1:3306/seata?useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai
store.db.user=root
store.db.password=123456

修改好這個文件以后,把這個文件放到seata目錄下:

把這些配置都加入到Nacos配置中,要借助一個腳本來進行執(zhí)行,官方已經提供好。

地址為:https://github.com/seata/seata/blob/develop/script/config-center/nacos/nacos-config.sh。

新建一個nacos-config.sh文件,將腳本內容復制進去,修改congfig.txt的路徑。

上述文件修改好后,打開git工具,將nacos-config.sh工具拖拽到窗體中即可或者使用命令。

sh nacos-config.sh -h 127.0.0.1 -p 8848 -g SEATA_GROUP -t 88b8f583-43f9-4272-bd46-78a9f89c56e8 -u nacos -w nacos。

-h:nacos地址。

-p:端口,默認8848。

-g:seata的服務列表分組名稱。

-t:nacos命名空間id。

-u和-w:nacos的用戶名和密碼。

最后會有四個執(zhí)行失敗,是因為redis報錯的關系,這個可以忽略,不影響正常使用。最后可以看到在Nacos中有很多的配置項,說明導入成功。再重新其中seata,成功監(jiān)聽到8091端口,表示前置工作都已經準備完成。

Seata的事務模式

Seata 定義了全局事務的框架,主要分為以下幾步:

  1. TM 向 TC請求 發(fā)起(Begin)、提交(Commit)、回滾(Rollback)等全局事務。
  2. TM把代表全局事務的XID綁定到分支事務上。
  3. RM向TC注冊,把分支事務關聯(lián)到XID代表的全局事務中。
  4. RM把分支事務的執(zhí)行結果上報給TC。
  5. TC發(fā)送分支提交(Branch Commit)或分支回滾(Branch Rollback)命令給RM。

Seata 的 全局事務 處理過程,分為兩個階段:

  • 執(zhí)行階段 :執(zhí)行分支事務,并保證執(zhí)行結果滿足是可回滾的(Rollbackable)持久化的(Durable)。
  • 完成階段:根據(jù) 執(zhí)行階段 結果形成的決議,應用通過 TM 發(fā)出的全局提交或回滾的請求給 TC,TC 命令 RM 驅動 分支事務 進行 Commit 或 Rollback。

Seata 的所謂事務模式是指:運行在 Seata 全局事務框架下的 分支事務 的行為模式。準確地講,應該叫作 分支事務模式。

不同的 事務模式 區(qū)別在于 分支事務 使用不同的方式達到全局事務兩個階段的目標。即,回答以下兩個問題:

  • 執(zhí)行階段 :如何執(zhí)行并 保證 執(zhí)行結果滿足是可回滾的(Rollbackable)持久化的(Durable)。
  • 完成階段:收到 TC 的命令后,如何做到分支的提交或回滾?

我們以AT模式為例:

  • 執(zhí)行階段:
  • 可回滾:根據(jù) SQL 解析結果,記錄回滾日志
  • 持久化:回滾日志和業(yè)務 SQL 在同一個本地事務中提交到數(shù)據(jù)庫
  • 完成階段:
  • 分支提交:異步刪除回滾日志記錄
  • 分支回滾:依據(jù)回滾日志進行反向補償更新

接下來就進入重頭戲,Seata四大模式的介紹。

Seata-XA模式

Seata 1.2.0 版本發(fā)布了新的事務模型:XA模式,實現(xiàn)了對XA協(xié)議的支持。對于XA模式我們需要從三個點去解析它。

  • XA模式是什么。
  • 為什么支持XA。
  • XA模式如何實現(xiàn)和使用。

XA模式簡介

首先需要知道XA模型是什么,XA 規(guī)范早在上世紀 90 年代初就被提出,用于解決分布式事務領域的問題,他也是最早的分布式事務處理方案,因為需要數(shù)據(jù)庫內部也是支持XA模式的,比如MYSQL,XA模式具有強一致性的特點,因此他對數(shù)據(jù)庫占用時間比較長,所以性能比較低。

XA模式屬于兩階段提交。

  1. 第一階段進行事務注冊,將事務注冊到TC中,執(zhí)行SQL語句。
  2. 第二階段TC判斷無事務出錯,通知所有事務提交,否則回滾。
  3. 在第一到第二階段過程中,事務一直占有數(shù)據(jù)庫鎖,因此性能比較低,但是所有事務要么一起提交,要么一起回滾,所以能實現(xiàn)強一致性。

無論是AT模式、TCC還是SAGA,這些模式的提出,都是源于XA規(guī)范對某些業(yè)務場景無法滿足。

什么是XA協(xié)議

XA規(guī)范是X/OPEN組織定義的分布式事務處理(DTP,Distributed Transaction Processing)標準,XA規(guī)范描述了全局事務管理器和局部資源管理器之間的接口,XA規(guī)范的目的是允許多個資源(如數(shù)據(jù)庫,應用服務器,消息隊列等)在同一事務中訪問,這樣可以使 ACID 屬性跨越應用程序而保持有效。

XA 規(guī)范 使用兩階段提交(2PC,Two-Phase Commit)來保證所有資源同時提交或回滾任何特定的事務。因為XA規(guī)范最早被提出,所以幾乎所有的主流數(shù)據(jù)庫都保有對XA規(guī)范的支持。

分布式事務DTP模型定義的角色如下:

  • AP:即應用程序,可以理解為使用DTP分布式事務的程序,例如訂單服務、庫存服務。
  • RM:資源管理器,可以理解為事務的參與者,一般情況下是指一個數(shù)據(jù)庫的實例(MySql),通過資源管理器對該數(shù)據(jù)庫進行控制,資源管理器控制著分支事務。
  • TM:事務管理器,負責協(xié)調和管理事務,事務管理器控制著全局事務,管理實務生命周期,并協(xié)調各個RM。全局事務是指分布式事務處理環(huán)境中,需要操作多個數(shù)據(jù)庫共同完成一個工作,這個工作即是一個全局事務。

DTP模式定義TM和RM之間通訊的接口規(guī)范叫XA,簡單理解為數(shù)據(jù)庫提供的2PC接口協(xié)議,基于數(shù)據(jù)庫的XA協(xié)議來實現(xiàn)的2PC又稱為XA方案。

現(xiàn)在有應用程序(AP)持有訂單庫和庫存庫,應用程序(AP)通過TM通知訂單庫(RM)和庫存庫(RM),進行扣減庫存和生成訂單,這個時候RM并沒有提交事務,而且鎖定資源。

當TM收到執(zhí)行消息,如果有一方RM執(zhí)行失敗,分別向其他RM也發(fā)送回滾事務,回滾完畢,釋放鎖資源。

當TM收到執(zhí)行消息,RM全部成功,向所有RM發(fā)起提交事務,提交完畢,釋放鎖資源。

分布式通信協(xié)議XA規(guī)范,具體執(zhí)行流程如下所示:

第一步:AP創(chuàng)建了RM1,RM2的JDBC連接。

第二步:AP通知生成全局事物ID,并把RM1,RM2注冊到全局事務ID。

第三步:執(zhí)行二階段協(xié)議中的第一階段prepare。

第四步:根據(jù)prepare請求,決定整體提交或回滾。

但是對于XA而言,如果一個參與全局事務的資源“失聯(lián)”了,那么就意味著TM收不到分支事務結束的命令,那么它鎖定的數(shù)據(jù),將會一直被鎖定,從而產生死鎖,這個也是Seata需要重點解決的問題。

在Seata定義的分布式事務架構中,利用事務資源(數(shù)據(jù)局、消息)等對XA協(xié)議進行支持,用XA協(xié)議的機制來管理分支事務。

  • 執(zhí)行階段:
  • 可回滾:業(yè)務SQL操作在XA分支中進行,有資源管理器對XA協(xié)議的支持來保證可回滾。
  • 持久化:ZA分支完成以后,執(zhí)行 XA prepare,同樣,由資源對XA協(xié)議的支持來保證持久化。
  • 完成階段:

XA存在的意義

  • 分支提交:執(zhí)行XA分支的commit。
  • 分支回滾:執(zhí)行XA分支的rollback。

Seata 已經支持了三大事務模式:AT\TCC\SAGA,這三個都是補償型事務,補償型事務處理你機制構建在 事務資源 之上(要么中間件層面,要么應用層),事務資源本身對于分布式的事務是無感知的,這種對于分布式事務的無感知存在有一個根本性的問題,無法做到真正的全局一致性。

例如一個庫存記錄,在補償型事務處理過程中,用80扣減為60,這個時候倉庫管理員查詢數(shù)據(jù)結果,看到的是60,之后因為異常回滾,庫存回滾到原來的80,那么這個時候庫存管理員看到的60,其實就是臟數(shù)據(jù),而這個中間狀態(tài)就是補償型事務存在的臟數(shù)據(jù)。

和補償型事務不同,XA協(xié)議要求事務資源 本身提供對規(guī)范和協(xié)議的支持,因為事務資源感知并參與分布式事務處理過程中,所以事務資源可以保證從任意視角對數(shù)據(jù)的訪問有效隔離性,滿足全局數(shù)據(jù)的一致性。

XA模式的使用

官方案例:https://github.com/seata/seata-samples。

項目名:seata-samples。

業(yè)務開始:business-xa庫存服務:stock-xa訂單服務:order-xa賬號服務:account-xa。

把這個項目案例下載下來以后,找到項目名為seata-xa的目錄,里面有測試數(shù)據(jù)庫的鏈接,如果不想用測試數(shù)據(jù)庫,只需要修改官方文檔中數(shù)據(jù)庫配置信息即可。

首先關注的是 business-xa項目,更多的關注BusinessService.purchase()方法。

@GlobalTransactional
public void purchase(String userId, String commodityCode, int orderCount, boolean rollback) {
String xid = RootContext.getXID();
LOGGER.info("New Transaction Begins: " + xid);
//調用庫存減庫存
String result = stockFeignClient.deduct(commodityCode, orderCount);
if (!SUCCESS.equals(result)) {
throw new RuntimeException("庫存服務調用失敗,事務回滾!");
}
//生成訂單
result = orderFeignClient.create(userId, commodityCode, orderCount);
if (!SUCCESS.equals(result)) {
throw new RuntimeException("訂單服務調用失敗,事務回滾!");
}
if (rollback) {
throw new RuntimeException("Force rollback ... ");
}
}

其實現(xiàn)方法較之前差不多,我們只需要在order-xa里面(OrderService.create),添加人為錯誤(int i = 1/0;)。

public void create(String userId, String commodityCode, Integer count) {
String xid = RootContext.getXID();
LOGGER.info("create order in transaction: " + xid);
int i = 1/0;
// 定單總價 = 訂購數(shù)量(count) * 商品單價(100)
int orderMoney = count * 100;
// 生成訂單
jdbcTemplate.update("insert order_tbl(user_id,commodity_code,count,money) values(?,?,?,?)",
new Object[] {userId, commodityCode, count, orderMoney});
// 調用賬戶余額扣減
String result = accountFeignClient.reduce(userId, orderMoney);
if (!SUCCESS.equals(result)) {
throw new RuntimeException("Failed to call Account Service. ");
}

}

里面有一個方法可以進行XA模式和AT模式的轉換OrderXADataSourceConfiguration.dataSource。

@Bean("dataSourceProxy")
public DataSource dataSource(DruidDataSource druidDataSource) {
// DataSourceProxy for AT mode
// return new DataSourceProxy(druidDataSource);
// DataSourceProxyXA for XA mode
return new DataSourceProxyXA(druidDataSource);
}

我們啟動這四個服務,訪問地址 http://localhost:8084/purchase。

我們可以其中報錯,然后再去看對應數(shù)據(jù)庫的數(shù)據(jù),沒有發(fā)生更改,說明我們的XA模式生效了,當你dubug去看里面的庫存服務的時候,當操作數(shù)據(jù)更改的時候,數(shù)據(jù)庫里面其實也是沒有記錄的,因為XA是強一致性,只有當事務結束完成以后,才會更改其中的數(shù)據(jù)。

XA模式的加入,補齊了Seata在全局一致性場景下的缺口,形成了AT、TCC、Saga、XA 四大事務模式的版圖,基本滿足了所有場景分布式事務處理的需求。

其中XA和AT是無業(yè)務侵入的,而TCC和Saga是有一定業(yè)務侵入的。

Seata-AT模式

先來介紹一下AT模式,AT模式是一種沒有侵入的分布式事務的解決方案,在AT模式下,用戶只需關注自己的業(yè)務SQL,用戶的業(yè)務SQL作為一階段,Seata框架會自動生成事務進行二階段提交和回滾操作。

兩階段提交協(xié)議的演變:

  • 一階段:業(yè)務數(shù)據(jù)和回滾日志記錄在同一個本地事務中提交,釋放本地鎖和連接資源。
  • 二階段:
    提交異步化,非??焖俚赝瓿?。
    回滾通過一階段的回滾日志進行反向補償。

AT模式主要特點

  1. 最終一致性。
  2. 性能較XA高。
  3. 只在第一階段獲取鎖,在第一階段進行提交后釋放鎖。

在一階段中,Seata會攔截 業(yè)務SQL ,首先解析SQL語義,找到要操作的業(yè)務數(shù)據(jù),在數(shù)據(jù)被操作前,保存下來記錄 undo log,然后執(zhí)行 業(yè)務SQL 更新數(shù)據(jù),更新之后再次保存數(shù)據(jù) redo log,最后生成行鎖,這些操作都在本地數(shù)據(jù)庫事務內完成,這樣保證了一階段的原子性。

相對一階段,二階段比較簡單,負責整體的回滾和提交,如果之前的一階段中有本地事務沒有通過,那么就執(zhí)行全局回滾,否在執(zhí)行全局提交,回滾用到的就是一階段記錄的 undo Log ,通過回滾記錄生成反向更新SQL并執(zhí)行,以完成分支的回滾。當然事務完成后會釋放所有資源和刪除所有日志。

AT流程分為兩階段,主要邏輯全部在第一階段,第二階段主要做回滾或日志清理的工作。流程如下:

從上圖中我們可以看到,訂單服務中TM向TC申請開啟一個全局事務,一般通過@GlobalTransactional標注開啟,TC會返回一個全局事務ID(XID),訂單服務在執(zhí)行本地事務之前,RM會先向TC注冊一個分支事務, 訂單服務依次生成undo log 執(zhí)行本地事務,生成redo log 提交本地事務,向TC匯報,事務執(zhí)行OK。

訂單服務發(fā)起遠程調用,將事務ID傳遞給庫存服務,庫存服務在執(zhí)行本地事務之前,先向TC注冊分支事務,庫存服務同樣生成undo Log和redo Log,向TC匯報,事務狀態(tài)成功。

如果正常全局提交,TC通知RM一步清理掉本地undo和redo日志,如果存在一個服務執(zhí)行失敗,那么發(fā)起回滾請求。通過undo log進行回滾。

在這里還會存在一個問題,因為每個事務從本地提交到通知回滾這段時間里面,可能這條數(shù)據(jù)已經被其他事務進行修改,如果直接用undo log進行回滾,可能會導致數(shù)據(jù)不一致的情況,

這個時候 RM會用 redo log進行驗證,對比數(shù)據(jù)是否一樣,從而得知數(shù)據(jù)是否有別的事務進行修改過,undo log是用于被修改前的數(shù)據(jù),可以用來回滾,redolog是用于被修改后的數(shù)據(jù),用于回滾校驗。

如果數(shù)據(jù)沒有被其他事務修改過,可以直接進行回滾,如果是臟數(shù)據(jù),redolog校驗后進行處理。

實戰(zhàn)

了解了AT模型的基本操作,接下來就來實戰(zhàn)操作一下,關于AT模型具體是如何實現(xiàn)的。首先設計兩個服務 cloud-alibaba-seata-order 和 cloud-alibaba-seata-stock。

表結構t_order、t_stock和undo_log三張表,項目源碼和表結構,加上undo_log表,此表用于數(shù)據(jù)的回滾,文末有鏈接。

cloud-alibaba-seata-order核心代碼如下:

controller:

@RestController
public class OrderController {
@Autowired
private OrderService orderService;
@GetMapping("order/create")
@GlobalTransactional //開啟分布式事務
public String create(){
orderService.create();
return "訂單創(chuàng)建成功!";
}
}

OrderService:

public interface OrderService {
void create();
}

StockClient:

@FeignClient(value = "seata-stock")
public interface StockClient {
@GetMapping("/stock/reduce")
String reduce();

}

OrderServiceImpl:

@Service
public class OrderServiceImpl implements OrderService{
@Autowired
private OrderMapper orderMapper;
@Autowired
private StockClient stockClient;
@Override
public void create() {
//扣減庫存
stockClient.reduce();
System.out.println("扣減庫存成功!");
//手工異常 用于回滾庫存信息
int i = 1/0;
System.err.println("異常!");
//創(chuàng)建訂單
orderMapper.createOrder();
System.out.println("創(chuàng)建訂單成功!");
}
}

OrderMapper:

@Mapper
public interface OrderMapper {
@Insert("insert into t_order (order_no,order_num) value (order_no+1,1)")
void createOrder();
}

cloud-alibaba-seata-stock核心代碼如下:

@RestController
public class StockController {
@Autowired
private StockService stockService;
@GetMapping("stock/reduce")
public String reduce(){
stockService.reduce();
return "庫存數(shù)量已扣減:"+ new Date();
}
}
public interface StockService {
void reduce();
}
@Service
public class StockServiceImpl implements StockService{
@Autowired
StockMapper stockMapper;
@Override
public void reduce() {
stockMapper.reduce();
}
}
@Mapper
@Repository
public interface StockMapper {
@Update("update t_stock set order_num = order_num - 1 where order_no = 1 ")
void reduce();

}

代碼都比較簡單,我們就不做過多的描述,基本注釋也都有,,首先我們需要將order和stock服務都跑起來,在之前我們的Nacos和Seata都要啟動起來,這個時候我們訪問order的Rest接口,http://localhost:8087/order/create,為了驗證undo_log的表是用于存儲回滾數(shù)據(jù),我們在OrderServiceImpl.create()中添加斷點,用debug的方式啟動。

然后訪問http://localhost:8087/order/create,當程序卡在這個節(jié)點的時間,我們去看undo_log和庫存表,會發(fā)現(xiàn),庫存確實減少了,而且undo_log也出現(xiàn)了對應的快照記錄修改當前的數(shù)據(jù)信息,這個數(shù)據(jù)就是用來回滾的數(shù)據(jù)。

但是當我們F9通過以后,庫存數(shù)量恢復,并且undo_log表的數(shù)據(jù)行也沒有了,這個時候證明我們的Seata事務生效,回滾成功。

到這里我們就驗證了AT事務的執(zhí)行過程,相比于XA和TCC等事務模型,Seata的AT模型可以應對大多數(shù)的業(yè)務場景,并且可以做到無業(yè)務侵入,開發(fā)者無感知,對于整個事務的協(xié)調、提交或者回滾操作,都可以通過AOP完成,開發(fā)者只需要關注業(yè)務即可。

由于Seata需要在不同的服務之間傳遞全局唯一的事務ID,和Dubbo等框架集成會比較友好,例如Dubbo可以用過隱士傳參來進行事務ID的傳遞,整個事務ID的傳播過程對開發(fā)者也可以做到無感知。

Seata-TCC模式

具體使用案例:https://seata.io/zh-cn/blog/integrate-seata-tcc-mode-with-spring-cloud.html。

什么是TCC

TCC 是分布式事務中的二階段提交協(xié)議,它的全稱為 Try-Confirm-Cancel,即資源預留(Try)、確認操作(Confirm)、取消操作(Cancel),他們的具體含義如下:

  1. Try:對業(yè)務資源的檢查并預留。
  2. Confirm:對業(yè)務處理進行提交,即 commit 操作,只要 Try 成功,那么該步驟一定成功。
  3. Cancel:對業(yè)務處理進行取消,即回滾操作,該步驟回對 Try 預留的資源進行釋放。

TCC 是一種侵入式的分布式事務解決方案,以上三個操作都需要業(yè)務系統(tǒng)自行實現(xiàn),對業(yè)務系統(tǒng)有著非常大的入侵性,設計相對復雜,但優(yōu)點是 TCC 完全不依賴數(shù)據(jù)庫,能夠實現(xiàn)跨數(shù)據(jù)庫、跨應用資源管理,對這些不同數(shù)據(jù)訪問通過侵入式的編碼方式實現(xiàn)一個原子操作,更好地解決了在各種復雜業(yè)務場景下的分布式事務問題。

TCC和AT區(qū)別

AT 模式基于 支持本地 ACID 事務 的 關系型數(shù)據(jù)庫:

  • 一階段 prepare 行為:在本地事務中,一并提交業(yè)務數(shù)據(jù)更新和相應回滾日志記錄。
  • 二階段 commit 行為:馬上成功結束,自動異步批量清理回滾日志。
  • 二階段 rollback 行為:通過回滾日志,自動生成補償操作,完成數(shù)據(jù)回滾。

相應的,TCC 模式,不依賴于底層數(shù)據(jù)資源的事務支持:

  • 一階段 prepare 行為:調用自定義的 prepare 邏輯。
  • 二階段 commit 行為:調用自定義的 commit 邏輯。
  • 二階段 rollback 行為:調用自定義的 rollback 邏輯。

所謂 TCC 模式,是指支持把 自定義 的分支事務納入到全局事務的管理中。

特點:

  1. 侵入性比較強,并且需要自己實現(xiàn)相關事務控制邏輯
  2. 在整個過程基本沒有鎖,性能較強

Seata-Saga模式

Saga模式是SEATA提供的長事務解決方案,在Saga模式中,業(yè)務流程中每個參與者都提交本地事務,當出現(xiàn)某一個參與者失敗則補償前面已經成功的參與者,一階段正向服務和二階段補償服務(執(zhí)行處理時候出錯了,給一個修復的機會)都由業(yè)務開發(fā)實現(xiàn)。

Saga 模式下分布式事務通常是由事件驅動的,各個參與者之間是異步執(zhí)行的,Saga 模式是一種長事務解決方案。

之前我們學習的Seata分布式三種操作模型中所使用的的微服務全部可以根據(jù)開發(fā)者的需求進行修改,但是在一些特殊環(huán)境下,比如老系統(tǒng),封閉的系統(tǒng)(無法修改,同時沒有任何分布式事務引入),那么AT、XA、TCC模型將全部不能使用,為了解決這樣的問題,才引用了Saga模型。

比如:事務參與者可能是其他公司的服務或者是遺留系統(tǒng),無法改造,可以使用Saga模式。

Saga模式是Seata提供的長事務解決方案,提供了異構系統(tǒng)的事務統(tǒng)一處理模型。在Saga模式中,所有的子業(yè)務都不在直接參與整體事務的處理(只負責本地事務的處理),而是全部交由了最終調用端來負責實現(xiàn),而在進行總業(yè)務邏輯處理時,在某一個子業(yè)務出現(xiàn)問題時,則自動補償全面已經成功的其他參與者,這樣一階段的正向服務調用和二階段的服務補償處理全部由總業(yè)務開發(fā)實現(xiàn)。

Saga狀態(tài)機

目前Seata提供的Saga模式只能通過狀態(tài)機引擎來實現(xiàn),需要開發(fā)者手工的進行Saga業(yè)務流程繪制,并且將其轉換為Json配置文件,而后在程序運行時,將依據(jù)子配置文件實現(xiàn)業(yè)務處理以及服務補償處理,而要想進行Saga狀態(tài)圖的繪制,一般需要通過Saga狀態(tài)機來實現(xiàn)。

基本原理:

  • 通過狀態(tài)圖來定義服務調用的流程并生成json定義文件。
  • 狀態(tài)圖中一個節(jié)點可以調用一個服務,節(jié)點可以配置它的補償節(jié)點。
  • 狀態(tài)圖 json 由狀態(tài)機引擎驅動執(zhí)行,當出現(xiàn)異常時狀態(tài)引擎反向執(zhí)行已成功節(jié)點對應的補償節(jié)點將事務回滾。
  • 可以實現(xiàn)服務編排需求,支持單項選擇、并發(fā)、子流程、參數(shù)轉換、參數(shù)映射、服務執(zhí)行狀態(tài)判斷、異常捕獲等功能。

Saga狀態(tài)機的應用

官方文檔地址:https://seata.io/zh-cn/docs/user/saga.html。

Seata Safa狀態(tài)機可視化圖形設計器使用地址:https://github.com/seata/seata/blob/develop/saga/seata-saga-statemachine-designer/README.zh-CN.md。

總結

總的來說在Seata的中AT模式基本可以滿足百分之80的分布式事務的業(yè)務需求,AT模式實現(xiàn)的是最終一致性,所以可能存在中間狀態(tài),而XA模式實現(xiàn)的強一致性,所以效率較低一點,而Saga可以用來處理不同開發(fā)語言之間的分布式事務,所以關于分布式事務的四大模型,基本可以滿足所有的業(yè)務場景,其中XA和AT沒有業(yè)務侵入性,而Saga和TCC具有一定的業(yè)務侵入。


本文標題:分布式事務(Seata)四大模式詳解
瀏覽路徑:http://m.5511xx.com/article/cdiieeg.html