Seata源碼—1.Seata分布式事務的模式簡介

大綱

1.Seata分布式事務框架簡介

2.Seata AT模式實現分布式事務的機制

3.Seata AT模式下的寫隔離機制

4.Seata AT模式下的讀隔離機制

5.官網示例說明Seata AT模式的工作機制

6.Seata TCC模式的介紹以及與AT模式區別

7.Seata Saga模式的介紹

8.單服務多個庫的分布式事務支持

9.Seata的AT、TCC、Saga三種模式對比

10.基于RocketMQ的可靠消息最終一致性事務

11.Seata官方分布式事務例子

1.Seata分布式事務框架簡介

(1)Seata的特色功能

(2)Seata的術語

Seata是一款分布式事務解決方案,為用戶提供了AT、TCC、SAGA和XA事務模式,致力于在微服務架構下提供高性能和簡單易用的分布式事務服務。

(1)Seata的特色功能

一.微服務框架集成支持

已支持Dubbo、Spring Cloud、Sofa-RPC、Motan和gRPC等RPC框架。

二.AT模式

提供無侵入自動補償的事務模式,目前已支持MySQL、Oracle、PostgreSQL、TiDB和MariaDB。

三.TCC模式

支持TCC模式并可與AT混用,靈活度更高。

四.SAGA模式

為長事務提供的解決方案,提供編排式與注解式。

五.XA模式

支持已實現XA接口的數據庫的XA模式,目前已支持MySQL、Oracle、TiDB和MariaDB。

六.高可用

支持計算分離集群模式,水平擴展能力強的數據庫和Redis存儲模式。

(2)Seata的術語

一.TC(Transaction Coordinator)—事務協調者

用來維護全局和分支事務的狀態,驅動全局事務提交或回滾。

二.TM(Transaction Manager)—事務管理器

用來定義全局事務的范圍:開始全局事務、提交或回滾全局事務。

三.RM(Resource Manager)—資源管理器

用來管理分支事務處理的資源,與TC交談以注冊分支事務和報告分支事務的狀態,并驅動分支事務提交或回滾。

2.Seata AT模式實現分布式事務的機制

(1)前提

(2)整體機制

(1)前提

一.基于支持本地ACID事務的關系型數據庫

二.Java應用 + 通過JDBC訪問數據庫

(2)整體機制

兩階段提交協議的演變:

一階段:首先業務數據和回滾日志記錄在同一個本地事務中提交,然后釋放本地鎖和連接資源。

二階段:提交異步化,非常快速地完成,回滾通過一階段的回滾日志進行反向補償。

3.Seata AT模式下的寫隔離機制

(1)Seata在AT模式下的寫隔離機制

(2)Seata在AT模式下的寫隔離例子

(3)Seata AT模式寫隔離下的補償執行

(4)為什么Seata AT模式要設計寫隔離機制

(1)Seata在AT模式下的寫隔離機制

一階段本地事務提交前,需要確保先拿到全局鎖。如果拿不到全局鎖,就不能提交本地事務。拿全局鎖的嘗試被限制在一定時間范圍內,超出時間范圍將被放棄,并回滾本地事務,釋放本地鎖。

(2)Seata在AT模式下的寫隔離例子

以一個示例來說明:兩個全局事務tx1和tx2,分別對m字段進行更新操作,m的初始值是1000。

tx1先開始,開啟本地事務,拿到本地鎖,更新操作m=1000-100=900。本地事務提交前,先拿到該記錄的全局鎖 ,本地事務提交后釋放本地鎖。

tx2后開始,開啟本地事務,拿到本地鎖,更新操作m=900-100=800。本地事務提交前,嘗試拿該記錄的全局鎖。

tx1全局提交前,該記錄的全局鎖被tx1持有,tx2需要重試等待獲取全局鎖。tx1二階段全局提交,釋放全局鎖。tx2拿到全局鎖后,提交其本地事務。

(3)Seata AT模式寫隔離下的補償執行

如果tx1的二階段全局回滾,則tx1需要重新獲取該數據的本地鎖,進行反向補償的更新操作,實現分支的回滾。

此時如果tx2仍在等待該數據的全局鎖,同時持有本地鎖,則tx1的分支回滾會失敗,tx1的分支回滾會一直重試,直到tx2的全局鎖等鎖超時,需要放棄全局鎖 + 回滾本地事務 + 釋放本地鎖,此時tx1的分支回滾才能最終成功。

(4)為什么Seata AT模式要設計寫隔離機制

由于整個過程全局鎖在tx1結束前一直是被tx1持有的,所以寫隔離機制可以保證不會發生臟寫的問題。

4.Seata AT模式下的讀隔離機制

(1)Seata AT模式的讀隔離機制介紹

(2)Seata AT模式的讀隔離機制實現

(1)Seata AT模式的讀隔離機制介紹

在數據庫本地事務隔離級別讀已提交(Read Committed)或以上的基礎上,Seata AT模式的默認全局隔離級別是讀未提交(Read Uncommitted)。

如果應用在特定場景下,必需要求全局的讀已提交,目前Seata的方式是通過SELECT FOR UPDATE語句的代理來實現。

(2)Seata AT模式的讀隔離機制實現

SELECT FOR UPDATE語句的執行會申請全局鎖。如果全局鎖被其他事務持有,則釋放本地鎖(回滾SELECT FOR UPDATE語句的本地執行)并重試。

在這個過程中,查詢是被阻塞住的。直到拿到全局鎖,即讀取的相關數據是已提交的,才返回。

出于總體性能上的考慮,Seata目前的方案并沒有對所有SELECT語句都進行代理,僅針對FOR UPDATE的SELECT語句。

5.官網示例說明Seata AT模式的工作機制

(1)一階段的工作過程

(2)二階段——回滾的工作過程

(3)二階段——提交的工作過程

(4)使用Seata AT模式需要創建回滾日志表

以一個示例來說明整個AT分支的工作過程:

業務表:product

+-------+--------------+-------+
| Field | Type         | Key   |
+-------+--------------+-------+
| id    | bigint(20)   | PRI   |
+-------+--------------+-------+
| name  | varchar(100) |       |
+-------+--------------+-------+
| since | varchar(100) |       |
+-------+--------------+-------+

AT分支事務的業務邏輯:

update product set name = 'GTS' where name = 'TXC';

(1)一階段的工作過程

步驟一:解析SQL得到SQL的類型、表、條件等相關的信息。比如類型是UPDATE、表是product、條件是where name = 'TXC'。

步驟二:查詢前鏡像。也就是根據解析得到的條件信息,生成查詢語句,定位數據。

select id, name, since from product where name = 'TXC';//得到前鏡像如下:
+-------+-------+-------+
| id    | name  | since |
+-------+-------+-------+
| 1     | TXC   |  2014 |
+-------+-------+-------+

步驟三:執行業務SQL。更新這條記錄的name為'GTS'。

步驟四:查詢后鏡像。根據前鏡像的結果,通過主鍵定位數據。

select id, name, since from product where id = 1;//得到后鏡像如下:
+-------+-------+-------+
| id    | name  | since |
+-------+-------+-------+
| 1     | GTS   |  2014 |
+-------+-------+-------+

步驟五:插入回滾日志。把前后鏡像數據以及業務SQL相關的信息組成一條回滾日志記錄,插入到UNDO_LOG表中。

{"branchId": 641789253,"undoItems": [{"afterImage": {"rows": [{"fields": [{"name": "id","type": 4,"value": 1}, {"name": "name","type": 12,"value": "GTS"}, {"name": "since","type": 12,"value": "2014"}]}],"tableName": "product"},"beforeImage": {"rows": [{"fields": [{"name": "id","type": 4,"value": 1}, {"name": "name","type": 12,"value": "TXC"}, {"name": "since","type": 12,"value": "2014"}]}],"tableName": "product"},"sqlType": "UPDATE"}],"xid": "xid:xxx"
}

步驟六:提交前向TC注冊分支。也就是申請product表中,主鍵值等于1的記錄的全局鎖。

步驟七:本地事務提交。業務數據的更新和前面步驟中生成的UNDO LOG一并提交。

步驟八:將本地事務提交的結果上報給TC

(2)二階段——回滾的工作過程

步驟一:收到TC的分支回滾請求,開啟一個本地事務執行如下操作。

步驟二:通過XID和Branch ID查找到相應的UNDO LOG記錄。

步驟三:拿UNDO LOG中的后鏡像與當前數據進行數據校驗。如果有不同,說明數據被當前全局事務之外的動作做了修改。這種情況,需要根據配置策略來做處理。

步驟四:根據UNDO LOG中的前鏡像和業務SQL信息生成并執行回滾語句。

步驟五:提交本地事務并把執行結果(即分支事務回滾的結果)上報給TC。

(3)二階段——提交的工作過程

步驟一:收到TC的分支提交請求,把請求放入一個異步任務的隊列中,然后馬上返回提交成功的結果給TC。

步驟二:異步任務階段執行分支提交請求,將異步和批量地刪除相應UNDO LOG記錄。

(4)使用Seata AT模式需要創建回滾日志表

CREATE TABLE `undo_log` (`id` bigint(20) NOT NULL AUTO_INCREMENT,`branch_id` bigint(20) NOT NULL,`xid` varchar(100) NOT NULL,`context` varchar(128) NOT NULL,`rollback_info` longblob NOT NULL,`log_status` int(11) NOT NULL,`log_created` datetime NOT NULL,`log_modified` datetime NOT NULL,PRIMARY KEY (`id`),UNIQUE KEY `ux_undo_log` (`xid`,`branch_id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;

6.Seata TCC模式的介紹以及與AT模式區別

(1)Seata TCC模式的介紹

(2)TCC模式與AT模式的區別

(1)Seata TCC模式的介紹

TCC = Try + Commit + Cancel。一個分布式的全局事務,整體是兩階段提交的模型。全局事務是由若干分支事務組成,分支事務要滿足兩階段提交的模型要求。

即需要每個分支事務都具備自己的:一階段Prepare行為(Try行為),二階段Commit或Rollback行為(Commit + Cancel行為)。

(2)TCC模式與AT模式的區別

所謂TCC模式,是指支持把自定義的分支事務納入到全局事務的管理中。其實一開始,Seata只有TCC模式,后來才加入AT模式。但TCC模式太麻煩了,每個功能都需要實現三套SQL邏輯,AT模式其實是對TCC模式的簡化。

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

一階段Prepare行為:在本地事務中,一起提交業務數據更新和相應回滾日志記錄。

二階段Commit行為:馬上成功結束,自動 + 異步 + 批量清理回滾日志。

二階段Rollback行為:通過回滾日志,自動生成補償操作,完成數據回滾。

TCC模式則不依賴于底層數據資源的事務支持:

一階段Prepare行為:調用自定義Prepare邏輯。

二階段Commit行為:調用自定義Commit邏輯。

二階段Rollback行為:調用自定義Rollback邏輯。

7.Seata Saga模式的介紹

Saga模式是Seata提供的長事務解決方案。在Saga模式中,業務流程中每個參與者都提交本地事務,當出現某一個參與者失敗則補償前面已經成功的參與者。一階段正向服務和二階段補償服務都由業務開發實現。

Saga模式的正向服務可以理解成是TCC模式的Try階段 + Commit階段,逆向補償服務可以理解成是TCC模式的Cancel階段。

一.適用場景

場景一:業務流程長、業務流程多

場景二:無法提供TCC模式要求的三個接口

比如參與者包含其它公司,或者遺留的老系統服務。

二.優勢

一階段提交本地事務,無鎖 + 高性能。

事件驅動架構,參與者可異步執行,高吞吐。

補償服務易于實現。

三.缺點

不保證隔離性,寫不隔離。

8.單服務多個庫的分布式事務支持

單個服務對接了多個庫。比如該服務處理一個請求時,需要更新多個數據庫。分支事務是分布在多個數據庫上的,并不是分布在多個服務上的。Seata也天然支持這種情況下的分布式事務。

每個數據庫上的事務也都會到Seata上注冊一個分支事務。注冊之后,各個分支事務也和Seata的AT模式一樣:申請本地鎖 + 生成undo log + 申請全局鎖 + 在其對應數據庫上提交增刪改。

9.Seata的AT、TCC、Saga三種模式對比

AT模式適用于底層存儲都相同的情況,比如都是MySQL等。一般選用AT模式即可,簡單方便。

TCC模式適用于底層存儲是異構的情況,比如MySQL + Redis + ES等。TCC模式一般在try階段寫入一條數據并標記未生效狀態,然后在commit階段才正式標記為正常生效狀態。

TCC模式最大的優點就是很靈活。即使事務失敗了,try階段寫入的數據基本也不會影響線上業務。TCC模式特別適用于異構存儲要支持事務的情況。

Saga模式適用于異構系統、長流程、改造成TCC特別復雜繁瑣的情況。

10.基于RocketMQ的可靠消息最終一致性事務

同步事務:在Seata的AT、TCC、Saga中選一種。

異步事務:使用RocketMQ的事務機制或者自己實現一套最終一致性事務框架。

11.Seata官方分布式事務例子

https://seata.io/zh-cn/docs/user/quickstart.html

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/80965.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/80965.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/80965.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

【Qt】之音視頻編程2:QtAV的使用篇

QtAV 基本播放控制功能實現&#xff08;C & QML&#xff09; QtAV 提供了完整的播放控制 API&#xff0c;支持 播放、暫停、停止、快進快退、截屏 等功能。以下是具體實現方法&#xff1a; 1. C 控制方式 基本播放控制 #include <QtAV> #include <QtAV/AVPlaye…

歌詞滾動效果

<!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><!-- 設置標簽頁圖標 --><link rel"shortcut icon&…

基于大模型的TIA診療全流程智能決策系統技術方案

目錄 一、多模態數據融合與預處理系統1.1 數據接入模塊1.2 數據預處理偽代碼二、TIA智能預測模型系統2.1 模型訓練流程2.2 混合模型架構偽代碼三、術中智能監測系統3.1 實時監測流程3.2 實時預測偽代碼四、智能診療決策系統4.1 手術方案推薦流程4.2 麻醉方案生成偽代碼五、預后…

Java 日期解析與格式化:從標準格式到自然語言解析

使用 Java 搭配 Apache Commons Lang3 和 Natty 庫&#xff0c;實現靈活高效的日期解析與格式化。 一、背景 將不同格式的日期統一成一個格式。日期格式可能有以下幾種類型&#xff1a; 標準格式&#xff1a;2024-02-28、14/05/2022、2002年5月6日非英文月份縮寫&#xff1a;…

Room持久化庫:從零到一的全面解析與實戰

簡介 在Android開發中,Room作為官方推薦的數據庫持久化庫,提供了對SQLite的抽象層,使得數據庫操作更加安全、高效且易于維護。 Room通過注解處理器和編譯時驗證,顯著降低了數據庫操作的復雜度,同時支持響應式編程模式,使開發者能夠輕松實現數據變化的實時監聽。對于企業…

MySQL(6)如何刪除數據庫和表?

在 MySQL 中刪除數據庫和表是常見的管理操作。下面將詳細介紹如何使用 SQL 語句以及圖形化工具來刪除數據庫和表。 步驟一&#xff1a;連接 MySQL 服務器 首先&#xff0c;連接到 MySQL 服務器&#xff0c;可以使用命令行工具 mysql 或圖形化工具如 MySQL Workbench。 使用命…

攜固態電池、新形態鋼殼疊片電池等產品 豪鵬科技將亮相CIBF 2025

攜固態電池、新形態鋼殼疊片電池等產品 豪鵬科技將亮相CIBF 2025 來源&#xff1a; 電池百人會-電池網 豪鵬科技&#xff08;展位號:14W001&#xff09;將攜固態電池、新形態鋼殼疊片電池及高安全性鈉離子電池等前沿技術產品亮相CIBF 2025&#xff0c;憑借多年的技術積累和產…

React學習———useEffect和useLayoutEffect

useEffect useEffect是React的一個Hook&#xff0c;用于在函數組件中處理副作用。副作用包括數據獲取、訂閱、手動DOM操作以及其他需要再渲染后執行的操作 基本用法 useEffect(() > {// 副作用邏輯return () > {// 可選的清理函數} }, [依賴數組])第一個參數&#xff…

“天神之眼”計算平臺的算力設計(預計500-1000 TOPS)

關于比亞迪“天神之眼”計算平臺的算力設計&#xff08;預計500-1000 TOPS&#xff09;&#xff0c;其技術路徑和行業意義值得深入探討。以下從實現方式、技術挑戰和行業影響三個維度展開分析&#xff1a; 1. 多芯片互聯的技術實現路徑 &#xff08;1&#xff09;芯片選型方案…

FPGA: Xilinx Kintex 7實現PCIe接口

在Xilinx Kintex-7系列FPGA上實現PCIe&#xff08;Peripheral Component Interconnect Express&#xff09;接口&#xff0c;通常使用Xilinx提供的7 Series Integrated Block for PCIe IP核&#xff0c;結合Vivado設計流程。以下是實現PCIe接口的詳細步驟和關鍵點&#xff0c;適…

ArcGIS Desktop使用入門(二)常用工具條——圖形

系列文章目錄 ArcGIS Desktop使用入門&#xff08;一&#xff09;軟件初認識 ArcGIS Desktop使用入門&#xff08;二&#xff09;常用工具條——標準工具 ArcGIS Desktop使用入門&#xff08;二&#xff09;常用工具條——編輯器 ArcGIS Desktop使用入門&#xff08;二&#x…

JT/T 808 通訊協議及數據格式解析

文章目錄 一、引言二、協議數據幀結構三、消息頭結構&#xff08;Message Header&#xff09;四、常用消息類型&#xff08;Message ID&#xff09;五、典型消息體結構解析六、數據轉義規則七、校驗碼計算方法八、終端與平臺通信流程示意&#xff08;簡要&#xff09;九、平臺接…

Rust 輸出到命令行

Rust 輸出到命令行 引言 Rust 是一門系統編程語言&#xff0c;以其高性能、內存安全、并發支持和零成本抽象等特性而聞名。在開發過程中&#xff0c;將 Rust 程序的輸出傳遞到命令行是常見的需求。本文將詳細介紹 Rust 輸出到命令行的多種方法&#xff0c;幫助讀者掌握這一技…

從字符串轉換到矩陣快速冪:解決多次轉換后的長度問題

引言 在編程競賽和算法問題中&#xff0c;我們經常會遇到需要對字符串進行多次轉換的問題。本文將介紹一個有趣的問題&#xff1a;給定一個字符串和轉換規則&#xff0c;計算經過多次轉換后字符串的長度。由于直接模擬會導致性能問題&#xff0c;我們將使用矩陣快速冪來高效解…

Vue2 elementUI 二次封裝命令式表單彈框組件

需求&#xff1a;封裝一個表單彈框組件&#xff0c;彈框和表單是兩個組件&#xff0c;表單組件以插槽的形式動態傳入彈框組件中。 外部組件使用的方式如下&#xff1a; 直接上代碼&#xff1a; MyDialog.vue 彈框組件 <template><el-dialog:titletitle:visible.syn…

React Hooks:從“這什么鬼“到“真香“的奇幻之旅

寫在前面:一個讓React老手都拍案叫絕的魔法 “等等,函數組件怎么能有狀態?!” —— 這是2018年我第一次聽說React Hooks時的反應。當時我正在用class組件寫一個復雜的表單,生命周期方法亂得像一碗意大利面。直到我看到了這段代碼: function Counter() {const [count, s…

論文閱讀筆記——雙流網絡

雙流網絡論文 視頻相比圖像包含更多信息&#xff1a;運動信息、時序信息、背景信息等等。 原先處理視頻的方法&#xff1a; CNN LSTM&#xff1a;CNN 抽取關鍵特征&#xff0c;LSTM 做時序邏輯&#xff1b;抽取視頻中關鍵 K 幀輸入 CNN 得到圖片特征&#xff0c;再輸入 LSTM&…

SpringBoot Vue MySQL酒店民宿預訂系統源碼(支付寶沙箱支付)+代碼講解視頻

&#x1f497;博主介紹&#x1f497;&#xff1a;?在職Java研發工程師、專注于程序設計、源碼分享、技術交流、專注于Java技術領域和畢業設計? 溫馨提示&#xff1a;文末有 CSDN 平臺官方提供的老師 Wechat / QQ 名片 :) Java精品實戰案例《700套》 2025最新畢業設計選題推薦…

右值引用的學習

傳統的C語法中就有引用的語法&#xff0c;而C11中新增了的右值引用語法特性&#xff0c;所以從現在開始我們之前學習的引用就叫做左值引用。無論左值引用還是右值引用&#xff0c;都是給對象取別名。 左值引用和右值引用 在講之前&#xff0c;我們先來看一下什么是左值和右值…

PHP黑白膠卷底片圖轉彩圖功能 V2025.05.15

關于底片轉彩圖 傳統照片底片是攝影過程中生成的反色圖像&#xff0c;為了欣賞照片&#xff0c;需要通過沖印過程將底片轉化為正像。而隨著數字技術的發展&#xff0c;我們現在可以使用數字工具不僅將底片轉為正像&#xff0c;還可以添加色彩&#xff0c;重現照片原本的色彩效…