日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

分布式事务Seata原理

發布時間:2024/9/30 编程问答 24 豆豆
生活随笔 收集整理的這篇文章主要介紹了 分布式事务Seata原理 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

一、Seata 介紹:

1、Seata 簡介:

????????Seata 是一款開源的分布式事務解決方案,致力于提供高性能與簡單易用的分布式事務服務,為用戶提供了 AT、TCC、SAGA 和 XA 幾種不同的事務模式:

  • AT模式:無侵入式的分布式事務解決方案,適合不希望對業務進行改造的場景,但由于需要添加全局事務鎖,對影響高并發系統的性能。該模式主要關注多DB訪問的數據一致性,也包括多服務下的多DB數據訪問一致性問題
  • TCC模式:高性能的分布式事務解決方案,適用于對性能要求比較高的場景。該模式主要關注業務拆分,在按照業務橫向擴展資源時,解決服務間調用的一致性問題
  • Saga模式:長事務的分布式事務解決方案,適用于業務流程長且需要保證事務最終一致性的業務系統。Saga 模式一階段就會提交本地事務,無鎖,長流程情況下可以保證性能,多用于渠道層、集成層業務系統,事務參與者可以是其它公司的服務也可以是遺留系統的服務,并且對于無法進行改造和提供 TCC 要求的接口,也可以使用 Saga 模式

2、Seata 的核心組件:

????????在 Seata 中主要有以下三種角色,其中 TM 和 RM 是作為 Seata 的客戶端與業務系統集成在一起,TC 作為 Seata 的服務端獨立部署:

  • 事務協調器(TC):維護全局事務的運行狀態,負責協調并驅動全局提交或回滾
  • 事務管理器(TM):事務發起方,控制全局事務的范圍,負責開啟一個全局事務,并最終發起全局提交或回滾全局的決議
  • 資源管理器(RM):事務參與方,管理本地事務正在處理的資源,負責向 TC 注冊本地事務、匯報本地事務狀態,接收 TC 的命令來驅動本地事務的提交或回滾

?3、Seata 的整體執行流程:

?Seata 分布式事務的整體執行機制如上圖所示,可以大致分為兩階段提交:

  • ① 發起方 TM 向 TC 申請開啟一個全局事務,全局事務創建成功并生成唯一的全局事務標識 XID,該 XID 在后續事務的服務調用鏈路的上下文傳播(通過Aop實現))
  • ② RM 向 TC 注冊分支事務,匯報資源準備狀況,并與 XID 進行綁定(Branch分支事務指分布式事務中每個獨立的本地局部事務)
  • ③ TM 向 TC 發起 XID 下的所有分支事務的全局提交或回滾請求(事務一階段結束)
  • ④ TC 匯總事務信息,決定分布式事務是提交還是回滾;
  • ⑤ TC 通知所有 RM 提交/回滾 資源,事務二階段結束;

二、Seata 的 AT 模式原理:

????????Seata AT模式是基于XA事務(XA是基于數據庫實現的分布式事務協議)演進而來,需要數據庫支持,如果是 MySQL,則需要5.6以上版本才支持XA協議。AT 模式的特點就是對業務無入侵式,用戶只需要關注自己的業務SQL,Seata 框架會在第一階段攔截并解析用戶的 SQL,并保存其變更前后的數據鏡像,形成undo log,并自動生成事務第二階段的提交和回滾操作。

1、AT 模式的整體執行流程:

?AT 模式 RM 驅動分支事務的行為分為以下兩個階段:

(1)執行階段:

  • (1)代理 JDBC 數據源,攔截并解析業務 SQL,生成更新前后的鏡像數據,形成 UNDO LOG。
  • (2)向 TC 注冊分支。
  • (3)分支注冊成功后,把業務數據的更新和 UNDO LOG 放在同一個本地事務中提交。

(2)完成階段:

  • 全局提交,收到 TC 的分支提交請求,異步刪除相應分支的 UNDO LOG。
  • 全局回滾,收到 TC 的分支回滾請求,查詢分支對應的 UNDO LOG 記錄,生成補償回滾的 SQL 語句,執行分支回滾并返回結果給 TC

2、AT 模式兩階段詳細流程:

2.1、第一階段的詳細執行流程:

????????在第一階段,RM 寫表時,Seata 通過代理數據源(從而達到對業務無侵入的效果)攔截業務 SQL 并 解析 SQL 語義,找到該 SQL 要更新的業務數據保存成 before image(前置鏡像),然后執行業務SQL,在業務數據更新后,再將其保存成 after image(后置鏡像),最后生成行鎖。通過把更新前后的業務數據數據鏡像組織成回滾日志 undo log,并利用本地事務的 ACID 特性,將業務數據的更新和回滾日志 undo log 的寫入在同一個本地事務中提交,保證任何提交的業務數據的更新一定有相應的回滾日志存在(即操作的原子性)。

????????基于這樣的機制,分支的本地事務就可以在全局事務的第一階段提交,并馬上釋放本地事務鎖定的資源,這也是 Seata 的 AT 模式和 XA 事務的不同之處,兩階段提交往往對資源的鎖定需要持續到第二階段實際的提交或者回滾操作,而有了回滾日志之后,可以在第一階段釋放對資源的鎖定,降低了鎖范圍,提高效率,即使第二階段發生異常需要回滾,只需找對 undo log 中對應數據鏡像并反解析成 SQL 來達到回滾目的

2.2、第二階段提交的詳細執行流程:

????????如果二階段的全局表決結果是提交的話,說明所有分支事務的業務SQL已經在第一階段生效,此時 Seata 框架只需異步刪除所有分支第一階段保存的鏡像數據、回滾日志和行鎖,完成數據清理即可,這個過程是非??焖俚?/p>

2.3、第二階段回滾的詳細執行流程:

?????????如果第二階段是回滾的話,Seata 就需要回滾第一階段已執行的 SQL 進行還原業務數據。由 TC 通知所有 RM 進行根據第一階段的回滾日志 undo log (即before image)進行反向補償,RM 收到 TC 發來的回滾請求后,通過 XID 和 Branch ID 找到相應的回滾日志記錄,通過undo log 生成反向的更新 SQL 并執行,以完成分支的業務數據還原,最后刪除 undo log、redo log 和行鎖。但在還原前需要校驗臟寫,對比數據庫”當前業務數據”和 “after image”,如果兩份數據完全一致就說明沒有臟寫,可以還原業務數據,如果不一致就說明有臟寫,出現臟寫就需要轉人工處理。

三、Seata 的 TCC、Saga、XA模式原理:

? ? ? ? 文章第二部分介紹了 Seata 的 AT 模式,接下來我們就介紹下 Seata 的其實幾種事務模式:

1、TCC 模式:

?TCC 模式 RM 驅動分支事務的行為分為以下兩個階段:

(1)執行階段:

  • ① 向 TC 注冊分支。
  • ② 執行業務定義的 Try 方法。
  • ③ 向 TC 上報 Try 方法執行情況:成功或失敗。

(2)完成階段:

  • 全局提交,收到 TC 的分支提交請求,執行業務定義的 Confirm 方法。
  • 全局回滾,收到 TC 的分支回滾請求,執行業務定義的 Cancel 方法。

2、Saga 模式:

Saga 模式 RM 驅動分支事務的行為包含以下兩個階段:

(1)執行階段:

  • ① 向 TC 注冊分支。
  • ② 執行業務方法。
  • ③ 向 TC 上報業務方法執行情況:成功或失敗。

(2)完成階段:

  • 全局提交,RM 不需要處理。
  • 全局回滾,收到 TC 的分支回滾請求,執行業務定義的補償回滾方法。

3、XA模式:

XA 模式 RM 驅動分支事務的行為包含以下兩個階段:

(1)執行階段:

  • ① 向 TC 注冊分支
  • ② XA Start,執行業務 SQL,XA End
  • ③ XA prepare,并向 TC 上報 XA 分支的執行情況:成功或失敗

(2)完成階段:

  • 收到 TC 的分支提交請求,XA Commit
  • 收到 TC 的分支回滾請求,XA Rollback

參考文章:

https://help.aliyun.com/document_detail/157850.html

https://blog.csdn.net/k6T9Q8XKs6iIkZPPIFq/article/details/107273472

四、SpringCloud Alibaba 整合 Seata AT 模式:

1、搭建 Seata TC 協調者:

1.1、下載 Seata TC 協調者:

????????Seata 的協調者其實就是阿里開源的一個服務,我們只需要下載(下載地址:https://github.com/seata/seata/releases)并啟動它,下載完成后,直接解壓即可,但是此時還不能直接運行,還需要做一些配置

?1.2、創建TC所需要的表:

https://github.com/seata/seata/tree/1.4.2/script/server/db

????????TC 運行需要將事務信息保存在數據庫,因此需要創建一些表,找到 seata-1.4.2 源碼的 script\server\db 這個目錄,將會看到以下SQL文件:

?以 MySQL 數據庫為例,創建數據庫 seata,并執行 mysql.sql 文件中的sql語句:

CREATE TABLE IF NOT EXISTS `global_table` (`xid` VARCHAR(128) NOT NULL,`transaction_id` BIGINT,`status` TINYINT NOT NULL,`application_id` VARCHAR(32),`transaction_service_group` VARCHAR(32),`transaction_name` VARCHAR(128),`timeout` INT,`begin_time` BIGINT,`application_data` VARCHAR(2000),`gmt_create` DATETIME,`gmt_modified` DATETIME,PRIMARY KEY (`xid`),KEY `idx_gmt_modified_status` (`gmt_modified`, `status`),KEY `idx_transaction_id` (`transaction_id`) ) ENGINE = InnoDBDEFAULT CHARSET = utf8;-- the table to store BranchSession data CREATE TABLE IF NOT EXISTS `branch_table` (`branch_id` BIGINT NOT NULL,`xid` VARCHAR(128) NOT NULL,`transaction_id` BIGINT,`resource_group_id` VARCHAR(32),`resource_id` VARCHAR(256),`branch_type` VARCHAR(8),`status` TINYINT,`client_id` VARCHAR(64),`application_data` VARCHAR(2000),`gmt_create` DATETIME(6),`gmt_modified` DATETIME(6),PRIMARY KEY (`branch_id`),KEY `idx_xid` (`xid`) ) ENGINE = InnoDBDEFAULT CHARSET = utf8;-- the table to store lock data CREATE TABLE IF NOT EXISTS `lock_table` (`row_key` VARCHAR(128) NOT NULL,`xid` VARCHAR(128),`transaction_id` BIGINT,`branch_id` BIGINT NOT NULL,`resource_id` VARCHAR(256),`table_name` VARCHAR(32),`pk` VARCHAR(36),`gmt_create` DATETIME,`gmt_modified` DATETIME,PRIMARY KEY (`row_key`),KEY `idx_branch_id` (`branch_id`) ) ENGINE = InnoDBDEFAULT CHARSET = utf8;

創建的三張表如下圖:

  • global_table:全局事務表,每當有一個全局事務發起后,就會在該表中記錄全局事務的ID
  • branch_table:分支事務表,記錄每一個分支事務的ID,分支事務操作的哪個數據庫等信息
  • lock_table:全局鎖

1.3、修改TC的注冊中心和配置中心:

????????找到 seata-server-1.4.2\seata\conf 目錄,其中有一個 registry.conf 文件,其中配置了TC的注冊中心和配置中心。默認的注冊中心是 file 形式,實際使用中肯定不能使用,需要改成Nacos形式;同樣 Seate 的 TC 的配置中心默認也是使用 file 形式,需要修改為 nacos 作為配置中心:

registry {# file 、nacos 、eureka、redis、zk、consul、etcd3、sofatype = "nacos"nacos {application = "seata-server"serverAddr = "localhost:8848"namespace = "XXXXXXXXXX"cluster = "default"username = "nacos"password = "nacos"} }config {# file、nacos 、apollo、zk、consul、etcd3type = "nacos"nacos {serverAddr = "localhost:8848"namespace = "XXXXXXXXXX"group = "SEATA_GROUP"username = "nacos"password = "nacos"} }

需要改動的地方如下:

  • type:改成nacos,表示使用nacos作為注冊中心或者配置中心
  • application:服務的名稱
  • serverAddr:nacos的地址
  • group:分組
  • namespace:命名空間
  • username:用戶名
  • password:密碼

上述配置修改好之后,在TC啟動的時候將會自動讀取 nacos 的配置,最后這份 registry.conf 文件的配置需要與下文每個seata客戶端項目中的配置一致

1.4、導入 seata Server 配置:

建議將 seata 項目下載到本地并閱讀 https://github.com/seata/seata/tree/1.4.2/script/config-center?路徑下的README.md內容

????????在上面我們已經配置好 seata TC 的配置中心,那么 TC 需要存儲到 Nacos 的配置都有哪些,如何推送過去呢?在 https://github.com/seata/seata/tree/1.4.2/script/config-center 中有一個 confIg.txt 文件,其中就是 TC 需要的全部配置,而 https://github.com/seata/seata/tree/1.4.2/script/config-center/nacos 中有一個 nacos-config.sh 腳本能夠將 config.txt 中的全部配置自動推送到nacos中。

????????我們先啟動nacos服務,然后在 nacos-config.sh 目錄下執行下面命令,將 config.txt 中的配置信息推送到 nacos 中:

# -h 代表nacos服務的IP;-p 代表nacos的端口號;-g 分組信息;-t 命名空間ID;-u 用戶名,-p 密碼

$ sh nacos-config.sh -h 127.0.0.1 -p 8080 -g SEATA_GROUP -t 7a7581ef-433d-46f3-93f9-5fdc18239c65 -u nacos -w nacos

命令執行成功后,就可以在nacos中看到如下配置:

?1.5、修改TC的事務信息存儲方式:

????????seata 的 TC 端的事務信息存儲模式(store.mode)現有file、db、redis三種,file模式無需改動,直接啟動即可,下面專門講下db和redis啟動步驟。

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

(1)以DB模式存儲:

????????db模式為高可用模式,全局事務會話信息通過db共享,相應性能差些;上一節的內容已經將所有的配置信息都推送到了Nacos中,TC啟動時會從Nacos中讀取,因此我們修改也需要在Nacos中修改。需要修改的配置如下:

## 采用db的存儲形式 store.mode=db ## druid數據源 store.db.datasource=druid ## mysql數據庫 store.db.dbType=mysql ## mysql驅動 store.db.driverClassName=com.mysql.jdbc.Driver ## TC的數據庫url store.db.url=jdbc:mysql://127.0.0.1:3306/seata_server?useUnicode=true ## 用戶名 store.db.user=root ## 密碼 store.db.password=Nov2014

?在nacos中搜索上述的配置,直接修改其中的值,比如修改 store.mode,如下圖:

?(2)以Redis模式存儲:

????????redis模式 Seata-Server 1.3 及以上版本支持,性能較高,但存在事務信息丟失風險,所以需要提前配置合適當前場景的redis持久化配置,該模式需改動以下配置:

store.mode=redis store.redis.host=127.0.0.1 store.redis.port=6379 store.redis.password=123456

1.6、啟動TC:

????????按照上述步驟全部配置成功后,則可以啟動TC,在 seata-server-1.4.2\bin 目錄下直接點擊 seata-server.bat(windows)運行,啟動成功后,啟動成功后,在Nacos的服務列表中則可以看到TC已經注冊進入,如下圖:

?至此,Seata 的 TC 就啟動完成了............

2、搭建Seata 客戶端(RM):

2.1、maven 添加 seata 依賴:

<dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-seata</artifactId><!-- 排除依賴,指定版本和服務端一致 --><exclusions><exclusion><groupId>io.seata</groupId><artifactId>seata-spring-boot-starter</artifactId></exclusion><exclusion><groupId>io.seata</groupId><artifactId>seata-all</artifactId></exclusion></exclusions> </dependency> <dependency><groupId>io.seata</groupId><artifactId>seata-spring-boot-starter</artifactId><version>1.4.2</version> </dependency> <dependency><groupId>io.seata</groupId><artifactId>seata-all</artifactId><version>1.4.2</version> </dependency>

注意:seata客戶端的依賴版本必須要和服務端一致。

2.2、application.yml 添加 seate 配置:

seata:# 這里要特別注意和nacos中配置的要保持一致,建議配置成 ${spring.application.name}-tx-grouptx-service-group: my_test_tx_groupregistry:type: nacosnacos:# 配置所在命名空間ID,如未配置默認public空間server-addr: 127.0.0.1:8848namespace: XXXXXXXXXXgroup: SEATA_GROUPapplication: seata-serveruserName: nacospassword: nacosconfig:type: nacosnacos:server-addr: 127.0.0.1:8848namespace: XXXXXXXXXXgroup: SEATA_GROUPuserName: nacospassword: nacos

tx-service-group 配置的值可以自定義,但是定義后需要在 nacos 配置中心新增 service.vgroupMapping.xxx=default 的配置,該屬性一定一定要和 seata 服務端的配置一致,否則不生效;比如上述配置中的,就需要在 nacos 配置中心新增一個配置項 service.vgroupMapping.my_test-tx-group=default,并且設置分組為SEATA_GROUP,如下圖:

注意:my_test-tx-group 僅僅是后綴,在nacos中添加配置時記得要加上前綴 service.vgroupMapping. ?

2.3、數據庫中添加回滾日志表:

https://github.com/seata/seata/tree/1.4.2/script/client/at/db

?回滾日志表:undo_log,這是Seata要求必須有的,每個業務庫都應該創建一個,SQL如下:

CREATE TABLE IF NOT EXISTS `undo_log` (`branch_id` BIGINT NOT NULL COMMENT 'branch transaction id',`xid` VARCHAR(128) NOT NULL COMMENT 'global transaction id',`context` VARCHAR(128) NOT NULL COMMENT 'undo_log context,such as serialization',`rollback_info` LONGBLOB NOT NULL COMMENT 'rollback info',`log_status` INT(11) NOT NULL COMMENT '0:normal status,1:defense status',`log_created` DATETIME(6) NOT NULL COMMENT 'create datetime',`log_modified` DATETIME(6) NOT NULL COMMENT 'modify datetime',UNIQUE KEY `ux_undo_log` (`xid`, `branch_id`) ) ENGINE = InnoDBAUTO_INCREMENT = 1DEFAULT CHARSET = utf8 COMMENT ='AT transaction mode undo table';

2.4、使用 seata 作為全局事務控制:

????????在分布式業務入口增加全局事務注解 @GlobalTransactional,其他 service 接口無需配置;假設A服務調用B服務,那么就在A服務的方法上面加入,B服務上面不用加

/*** seata 的 GlobalTransactional 注解只需要加載分布式業務入口處,其他service接口無需配置,從而實現分布式事務*/@GlobalTransactional@PostMapping (value = "addOrder",produces = {"application/json;charset=utf-8"})public String addOrder(@RequestParam String title, @RequestParam int price, @RequestParam int shopId, @RequestParam int userId){shopOrderService.save(ShopOrderPojo.builder().price(price).title(title).shopId(shopId).userId(userId).build());storageFeignService.reduceStorage(shopId, 1);return "success";}

備注:如果你進行異常捕捉,seata 將認為你已進行異常處理,就不會回滾數據了

  • (1)比如如果你配置了@ControllerAdvice將可能導致數據不回滾
  • (2)如果使用 Feign 調用分布式服務并配置了fallback,后面服務拋出異常會直接執行fallback導致無法回滾(rollbackFor = Exception.class);這時可以在fallback的實現方法內手動調用seata全局回滾,如下所示:
@Overridepublic BizResponse insertAge(Integer age) {//feign調用接口fallback后需要手動調用全局事務回滾try {String xid = RootContext.getXID();GlobalTransactionContext.reload(xid).rollback();} catch (TransactionException e) {e.printStackTrace();}return BizResponse.fail("客戶端降級處理insertAge," + Thread.currentThread().getName());}

2.5、undo log 表介紹:

????????上面介紹過 Seata 是根據 undo_log 中的記錄來回滾的,但是異?;貪L后 undo_log 表卻為空?怎么回事,這是因為 undo_log 日志被刪除了,想要看到undo_log 表中記錄,我們需要打斷點來看,在異常還沒拋出時打斷點,然后看下數據庫 undo_log 表中數據情況:

undo log 表簡單介紹:https://blog.csdn.net/hosaos/article/details/89136666

?

?

參考文章:

Seata 官方文檔:https://seata.io/zh-cn/docs/overview/what-is-seata.html

https://blog.csdn.net/qq_34162294/article/details/120984951

總結

以上是生活随笔為你收集整理的分布式事务Seata原理的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 国产污视频在线观看 | 国产激情av一区二区三区 | 中字幕视频在线永久在线观看免费 | 免费无遮挡网站 | 在线观看国产日韩 | 免费黄色网址大全 | 一级黄色片毛片 | 免费裸体美女网站 | 校园春色自拍偷拍 | 国产欧美日韩另类 | 免费观看nba乐趣影院 | 黄色av高清 | 国产波霸爆乳一区二区 | 国产精品5区| 国产精品888 | 神马午夜不卡 | 欧美一区二区三区激情 | 啪啪自拍视频 | 精品自拍偷拍视频 | 久久视频一区 | 男女一级片 | 欧美日韩在线视频一区二区三区 | 欧美乱三级 | 精品国产高清在线观看 | 久久色网站 | 成人宗合网 | 成人午夜影视在线观看 | 偷拍一区二区 | 96av视频| 国产999精品视频 | 色综合天天色综合 | 尤物天堂| 国产五月婷婷 | m3u8成人免费视频 | 暖暖成人免费视频 | 日韩精品一区二区三区中文字幕 | 国产免费一区二区三区四区五区 | 91视频精品 | 7x7x7x人成影视 | 久久久久999| 污导航在线 | 亚洲成人黄 | 操极品| 91毛片在线观看 | 色狠狠一区 | 沟厕沟厕近拍高清视频 | 狠狠人妻久久久久久综合蜜桃 | 在线观看免费毛片 | 国产原创91| 国产真实夫妇交换视频 | 国产91视频在线观看 | 不用播放器的av网站 | 艳妇乳肉豪妇荡乳av | 欧美成人免费看 | 国产成人免费av一区二区午夜 | 中文字幕一区在线播放 | 国产成人久久精品麻豆二区 | www.97视频| 狠狠干天天爱 | 懂色av一区二区三区在线播放 | 国产裸体无遮挡 | 午夜精品一区二区三区在线 | 直接看毛片 | 欧美精品一区二区三区视频 | 99久久精品无免国产免费 | 国产偷人妻精品一区二区在线 | 麻豆精品 | 韩日毛片| 久久人人澡 | 久久国产精品无码一区二区 | 日本欧美韩国国产精品 | 日本视频中文字幕 | 岳狂躁岳丰满少妇大叫 | www.97ai.com| 日韩精品免费一区二区 | 人人澡人人插 | 91九色网站| 中文字幕亚洲欧美日韩在线不卡 | 国产亚洲天堂网 | 欧美色成人 | 久久爱一区 | 亚洲无码精品一区二区三区 | 日本不卡视频在线 | 亚洲区精品 | 成人涩涩网 | 久久久久久久久久久久电影 | 1024国产视频 | 高潮疯狂过瘾粗话对白 | 男女涩涩网站 | 国产剧情av麻豆香蕉精品 | 亚洲一区日本 | 男生把女生困困的视频 | 91午夜理伦私人影院 | 国产精品天天狠天天看 | 日韩小视频在线观看 | 色婷婷av一区二区三区在线观看 | 黄色国产小视频 | av免费网址在线观看 | 久久嫩草精品久久久久 |