Seata架构篇 - AT模式

Seata是一款高性能的分布式事务解决方案,采用AT模式提供非侵入式的事务处理。AT模式基于X/Open DTP模型,包括TM、RM和TC三个角色。在AT模式中,业务数据和回滚日志在同一个本地事务提交,二阶段提交异步化,确保事务的高性能。Seata在读写隔离方面,通过全局锁避免脏读和脏写,同时在读已提交或以上隔离级别的数据库上,默认全局事务为读未提交隔离级别。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

前言

Seata 是一款开源的分布式事务解决方案,致力于提供高性能和简单易用的分布式事务服务。Seata 将为用户提供了 AT、TCC、SAGA 和 XA 事务模式,为用户打造一站式的分布式解决方案。

X/Open DTP Model

X/Open DTP Model 是 X/Open 组织定义的一套分布式事务的标准,也就是定义了分布式事务处理的规范和 API 接口,但是具体实现由各厂商自行实现。

image.png

TM、RM 作为 Seata 的客户端与业务系统集成在一起,TC 作为 Seata 的服务端独立部署。

TC(Transaction Coordinator)- 事务协调者

维护全局和分支事务的状态,驱动全局事务提交或回滚。

TM(Transaction Manager)- 事务管理器

管理全局事务,包括开始全局事务、提交或回滚全局事务。

RM(Resource Manager)- 资源管理器

管理分支事务,包括向 TC 注册分支事务和报告分支事务的状态,并驱动分支事务提交或回滚。

在 Seata 中,分布式事务的执行流程:

  • TM 开启分布式事务(TM 向 TC 注册全局事务记录)
  • 按业务场景,编排数据库、服务等事务资源(RM 向 TC 汇报资源准备状态)
  • TM 结束分布式事务,事务阶段一结束(TM 通知 TC 提交/回滚分布式事务)
  • TC 汇总事务信息,决定分布式事务提交还是回滚
  • TC 通知所有 RM 提交/回滚,事务二阶段结束

AT 模式

概述

Seata AT 模式是一种非侵入式的分布式事务解决方案,Seata 在内部做了对数据库操作的代理层,我们使用 Seata AT 模式时,实际上用的是 Seata 自带的数据源代理 DataSourceProxy,Seata 在这层代理中加入了很多逻辑,比如插入回滚 undo_log 日志,检查全局锁等。

为什么要检查全局锁呢,这是由于 Seata AT 模式的事务隔离是建立在分支事务的本地隔离级别基础之上的,在数据库本地隔离级别读已提交或以上的前提下,Seata 设计了由事务协调器维护的全局写排他锁,来保证事务间的写隔离,同时,将全局事务默认定义在读未提交的隔离级别上。

Seata 的事务是一个全局事务,它包含了若干个分支本地事务,在全局事务执行过程中(全局事务还没执行完),某个本地事务提交了,如果 Seata 没有采取任何措施,则会导致已提交的本地事务被读取,造成脏读,如果数据在全局事务提交前已提交的本地事务被修改,则会造成脏写。

一阶段:业务数据和回滚日志在同一个本地事务提交,释放本地锁和连接资源。

二阶段:提交异步化,非常快速地完成。回滚通过一阶段的回滚日志反向补偿。

Seata AT模式隔离级别解读

适用场景

  • 基于支持本地 ACID 事务的关系型数据库。
  • Java 应用,通过 JDBC 访问数据库。

原理

一阶段

1、解析 SQL。得到 SQL 的类型(UPDATE)、表(product)、条件(where name = ‘TXC’)等相关的信息。

2、查询前镜像:根据解析得到的条件信息,生成查询语句,定位数据。

select id, name, since from product where name = 'TXC';

得到前镜像:

id name since
1 TXC 2014

3、执行业务 SQL。更新这条记录的 name 为 ‘GTS’。

4、查询后镜像:根据前镜像的结果,通过 主键 定位数据。

得到后镜像:

id name since
1 GTS 2014

5、插入回滚日志:把前后镜像数据以及业务 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"
}

6、提交前,向 TC 注册分支:申请 product 表中,主键值等于 1 的记录的 全局锁

7、本地事务提交:业务数据的更新和前面步骤中生成的 UNDO LOG 一并提交。

8、将本地事务提交的结果上报给 TC。

二阶段

回滚

1、收到 TC 的分支回滚请求,开启一个本地事务,执行如下操作。

2、通过 XID 和 Branch ID 查找到相应的 UNDO LOG 记录。

3、数据校验:拿 UNDO LOG 中的后镜与当前数据进行比较,如果有不同,说明数据被当前全局事务之外的动作做了修改。这种情况,需要根据配置策略来做处理,详细的说明在另外的文档中介绍。

4、根据 UNDO LOG 中的前镜像和业务 SQL 的相关信息生成并执行回滚的语句:

update product set name = 'TXC' where id 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值