Seata

本文深入探讨了事务的ACID特性,包括原子性、一致性、隔离性和持久性。接着介绍了分布式事务的概念及其组成部分,并详细阐述了二阶段提交协议的工作流程。最后,重点讲解了Seata作为一款开源的分布式事务解决方案,其角色划分、工作原理及如何实现分布式事务的提交、回滚。Seata通过AT模式提供高性能的分布式事务服务,确保在微服务架构下的数据一致性。

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

Seata

一:什么是事务?

1.1)什么是事物?

事务是逻辑上的一组执行单元,要么都执行,要么都不执行.
1.2)事物的特性(ACID)

ACID是指数据库管理系统DBMS中事物所具有四个特性 eg:在数据库系统中,一个事务由一系列的数据库操作组成一个完整的逻辑过程,比如银行转账,从原账户扣除金额,目标账户增加金额

①:atomicity【原子性】

原子性表现为操作不能被分割,那么这二个操作 要么同时完成,要么就全部不完成,若事务出错了,那么事务就会回滚

②:Consistency【一致性】

一致性也比较容易理解,也就是说数据库要一直处于一致的状态,事务开始前是一个一致状态,事务结束后是另一个一致状态, 事务将数据库从一个一致状态转移到另一个一致状态

③:Isolation【隔离性】

所谓的独立性就是指并发的事务之间不会互相影响,如果一个事务要访问的数据正在被另外一个事务修改,只要另外一个事务还未提交,它所访问的数据就不受未提交事务的影响。 换句话说,一个事务的影响在该事务提交前对其它事务是不可见的

④:Durability【持久性】

若事务已经提交了,那么就回在数据库中永久的保存下来

二:什么是分布式事务?

分布式事务

分布式事务:就是把各个节点上的微服务的本地事务 结合起来,看成一个整体的事务。

分布式事务组成部分

①:事务参与者

(就是我们的一个一个的微服务,比如订单服务,库存服务)

②:资源服务器

(说白了就是我们的对应微服务连接的数据库 比如订单库,库存库)

③:事务管理器

(用于决策各个事务参数者的提交和回滚)

二阶段提交

1.准备阶段

1.准备阶段:事务协调者(事务管理器)给每个参与者(资源管理器)发送Prepare消息,每个参与者要么直接返回失败(如权限验证失败),要么在本地执行事务,写本地的redo和undo日志,但不提交。 第一阶段会占用数据库连接

2.提交阶段

如果协调者收到了参与者的失败消息或者超时,直接给每参与者发送回滚(Rollback)消息;否则,发送提交(Commit)消息;参与者根据协调者的指令执行提交或者回滚操作,释放所有事务处理过程中使用的锁资源。(注意:必须在最后阶段释放锁资源)

三:什么是Seata?

Seata 是一款开源的分布式事务解决方案,致力于提供高性能和简单易用的分布式事务服务。Seata 将为用户提供了 AT、TCC、SAGA 和 XA 事务模式,为用户打造一站式的分布式解决方案(AT模式是阿里首推的模式,阿里云上有商用版本的GTS[Global Transaction service 全局事务服务] ) 。

1.角色划分

RM(ResourceManager 资源管理者)

理解为 我们的一个一个的微服务 也叫做事务的参与者.

TM(TranactionManager 事务管理者)

也是我们的一个微服务,充当全局事务的发起者(决定了全局事务的开启,回滚,提交等)

凡是我们的微服务中标注了@GlobalTransactional ,那么该微服务就会被看出一个TM。我们业务场景中订单微服务就是一个事务发起者,同时也是一个RM

TC(TranactionController 全局事务的协调者)

这里就是我们的Seata-server,用来保存全局事务,分支事务,全局锁等记录,然后会通知各个RM进行回滚或者提交.

2.整体机制(两阶段提交协议的演变)

核心逻辑

set autocommit = 0;

select * from product where product_id=1 for update;

UPDATE Product SET count = count ‐ 1 WHERE product_id=1;

select * from product where product_id=1 for update;
commit;
对应的核心代码逻辑

connectionProxy.setAutoCommit(false);
return new LockRetryPolicy(connectionProxy.getTargetConnection()).execute(()‐> {
T result = executeAutoCommitFalse(args);
connectionProxy.commit();
return result;
});
2.1)工作原理

执行业务SQL update product set name = ‘GTS’ where name = ‘TXC’;

第一阶段:

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

2:查询前镜像:根据解析得到的条件信息,生成查询语句,定位数据。 select id, name, since from product where name = ‘TXC’;

3:执行业务 SQL:更新这条记录的 name 为 ‘GTS’。 update product set name = ‘GTS’ where name = ‘TXC’;

4:查询后镜像:根据前镜像的结果,通过 主键 定位数据 select id, name, since from product where id = 1`;

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 的相关信息生成并执行回滚的语句
5:提交本地事务。并把本地事务的执行结果(即分支事务回滚的结果)上报给 TC。
提交

1:收到 TC 的分支提交请求,把请求放入一个异步任务的队列中,马上返回提交成功的结果给 TC。
2:异步任务阶段的分支提交请求将异步和批量地删除相应 UNDO LOG 记录。

### Seata 分布式事务框架介绍 Seata 是一款开源的分布式事务解决方案,致力于提供高性能和简单易用的分布式事务服务[^3]。它融合了阿里巴巴和蚂蚁金服在分布式事务技术上的积累,并沉淀了新零售、云计算和新金融等场景下丰富的实践经验[^1]。Seata 提供了多种事务模式,包括 AT 模式(推荐)、TCC 模式、SAGA 模式和 XA 模式,为用户打造了一站式的分布式事务解决方案。 通过合理配置和优化,Seata 能够有效解决分布式系统的事务一致性问题,适用于电商、金融、物流等多种业务场景。实际使用时应根据业务特点选择合适的模式,配合完善的监控体系和运维方案,保证系统的高可用性和数据一致性[^2]。 --- ### Seata 分布式事务框架的使用步骤 #### 1. 引入依赖 在项目中引入 Seata 的相关依赖。以下是一个 Maven 项目的依赖示例: ```xml <dependency> <groupId>io.seata</groupId> <artifactId>seata-spring-boot-starter</artifactId> <version>1.5.0</version> <!-- 根据需要选择版本 --> </dependency> ``` #### 2. 配置事务切面和数据源代理 在 Spring Boot 项目中,取消默认的数据源自动创建,改为使用自定义的数据源,并配置事务切面。以下是主启动类的代码示例: ```java package cn.kt.springcloud; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration; import org.springframework.cloud.client.discovery.EnableDiscoveryClient; import org.springframework.cloud.openfeign.EnableFeignClients; @SpringBootApplication(exclude = DataSourceAutoConfiguration.class) @EnableDiscoveryClient @EnableFeignClients public class SeataOrderMainApp2001 { public static void main(String[] args) { SpringApplication.run(SeataOrderMainApp2001.class, args); } } ``` #### 3. 添加 `@GlobalTransactional` 注解 在需要开启分布式事务的业务方法上添加 `@GlobalTransactional` 注解。例如: ```java import io.seata.spring.annotation.GlobalTransactional; @Service public class OrderService { @Autowired private OrderMapper orderMapper; @GlobalTransactional public void createOrder(Order order) { // 执行订单创建逻辑 orderMapper.insert(order); // 假设调用其他微服务完成支付 paymentService.pay(order.getOrderId(), order.getAmount()); } } ``` #### 4. 配置文件 在 `application.yml` 或 `application.properties` 文件中,配置 Seata 的相关参数。以下是一个简单的配置示例: ```yaml spring: cloud: alibaba: seata: tx-service-group: my_tx_group # 定义事务组名称 seata: enabled: true service: vgroup-mapping: my_tx_group: default # 映射事务组到具体的事务管理器 grouplist: default: 127.0.0.1:8091 # Seata Server 地址 ``` --- ### Seata 的核心概念原理 #### 1. 三大角色 Seata 的三大核心角色分别为 TM(Transaction Manager)、RM(Resource Manager)和 TC(Transaction Coordinator)[^3]: - **TM**:事务管理器,负责协调整个分布式事务的提交或回滚。 - **RM**:资源管理器,负责管理本地资源(如数据库连接),并将其注册到 TC 中。 - **TC**:事务协调器,作为独立的服务运行,负责维护全局事务的状态并驱动事务的提交或回滚。 #### 2. AT 模式 AT 模式Seata 推荐使用的事务模式,具有高效性和易用性。其主要特点如下: - **一阶段提交**:执行业务 SQL 并生成 Undo Log。 - **二阶段提交**:根据全局事务的状态决定提交或回滚回滚时通过 Undo Log 还原数据状态[^5]。 --- ### 示例代码 以下是一个完整的 Seata 使用示例: #### 主启动类 ```java package com.example.seata; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration; import org.springframework.cloud.client.discovery.EnableDiscoveryClient; @SpringBootApplication(exclude = DataSourceAutoConfiguration.class) @EnableDiscoveryClient public class SeataDemoApplication { public static void main(String[] args) { SpringApplication.run(SeataDemoApplication.class, args); } } ``` #### 数据源配置 ```yaml spring: datasource: url: jdbc:mysql://localhost:3306/seata_db?useUnicode=true&characterEncoding=utf-8&serverTimezone=UTC username: root password: root driver-class-name: com.mysql.cj.jdbc.Driver ``` #### 业务服务类 ```java import io.seata.spring.annotation.GlobalTransactional; @Service public class OrderService { @Autowired private OrderMapper orderMapper; @Autowired private PaymentService paymentService; @GlobalTransactional public void placeOrder(Order order) { // 创建订单 orderMapper.insert(order); // 调用支付服务 paymentService.pay(order.getOrderId(), order.getAmount()); } } ``` --- ### 注意事项 1. 确保 Seata Server 已经正确部署并运行。 2. 配置好 Undo Log 表结构,Seata 默认会自动创建 Undo Log 表。 3. 根据业务需求选择合适的事务模式,例如 AT 模式适合大多数场景,而 TCC 模式适合对性能要求较高的场景。 ---
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值