Seata 是一个开源的分布式事务解决方案,它由阿里巴巴开源,专注于解决微服务架构中的分布式事务问题。它支持高性能的分布式事务处理,提供了多种事务模型(AT、TCC、SAGA 和 XA),并与 Spring Boot 和 Spring Cloud 深度集成。
以下是关于 Seata 的详细介绍、使用场景以及集成方法。
1. Seata 的核心概念
1.1 分布式事务的挑战
- 在微服务架构中,每个服务通常拥有独立的数据库,传统的本地事务无法跨服务进行控制。
- 常见的分布式事务场景:
- 创建订单时,需要同时扣减库存和支付金额。
- 资金转账系统,涉及多个账户的资金一致性。
1.2 Seata 的架构
-
Transaction Coordinator (TC)
- 事务协调者,管理全局事务的生命周期。
- 负责维护全局事务状态,并协调各分支事务的提交或回滚。
-
Transaction Manager ™
- 事务管理器,定义全局事务的范围,发起事务的提交或回滚。
-
Resource Manager (RM)
- 资源管理器,管理分支事务的资源(如数据库连接)。
- 负责提交或回滚分支事务。
2. 事务模型
2.1 AT 模式(Automatic Transaction)
- 自动事务管理,基于二阶段提交协议(2PC)。
- 适用于关系型数据库事务(MySQL、PostgreSQL 等)。
- 阶段 1:业务方法执行,生成回滚日志。
- 阶段 2:
- 提交: 事务成功时,提交操作。
- 回滚: 事务失败时,根据回滚日志恢复数据。
2.2 TCC 模式(Try-Confirm-Cancel)
- 手动定义分支事务的三个阶段:
- Try:预留资源。
- Confirm:提交操作。
- Cancel:释放资源。
- 适用于需要高性能和自定义事务控制的场景。
2.3 SAGA 模式
- 基于长事务的补偿机制,每个步骤都有前向和回滚操作。
- 适用于业务操作复杂、状态可补偿的场景。
2.4 XA 模式
- 基于数据库的两阶段提交协议(XA)。
- 性能较差,适用于事务一致性要求极高的场景。
3. Seata 的使用场景
- 电商系统:
- 创建订单时,扣减库存、扣款,确保一致性。
- 支付系统:
- 资金转账,多个账户的余额修改。
- 物流系统:
- 订单发货后,更新库存和物流状态。
- 金融系统:
- 贷款审批,涉及账户、利息、合同等多个系统。
4. Seata 的集成步骤
4.1 环境准备
下载和启动 Seata Server
- 下载 Seata Server:Seata GitHub。
- 修改
conf/registry.conf
配置文件,指定注册中心和配置中心(如 Nacos)。
registry {type = "nacos"nacos {serverAddr = "127.0.0.1:8848"namespace = ""group = "SEATA_GROUP"}
}
config {type = "nacos"nacos {serverAddr = "127.0.0.1:8848"namespace = ""group = "SEATA_GROUP"dataId = "seata.properties"}
}
- 启动 Seata Server:
sh bin/seata-server.sh -p 8091 -m file
4.2 Spring Boot 集成
依赖引入
在 pom.xml
中添加依赖:
<dependency><groupId>io.seata</groupId><artifactId>seata-spring-boot-starter</artifactId><version>1.6.1</version>
</dependency>
配置 Seata
在 application.yml
中添加配置:
seata:enabled: truetx-service-group: my_tx_group
spring:datasource:url: jdbc:mysql://127.0.0.1:3306/test?useUnicode=true&characterEncoding=utf-8&useSSL=falseusername: rootpassword: root
创建全局事务
使用 @GlobalTransactional
注解开启分布式事务:
@Service
public class OrderService {@Autowiredprivate InventoryService inventoryService;@Autowiredprivate PaymentService paymentService;@GlobalTransactional(name = "create-order", rollbackFor = Exception.class)public void createOrder(Order order) {// 保存订单orderRepository.save(order);// 扣减库存inventoryService.deductStock(order.getProductId(), order.getQuantity());// 扣款paymentService.processPayment(order.getUserId(), order.getTotalAmount());// 如果出现异常,全局回滚if (order.getTotalAmount().compareTo(BigDecimal.ZERO) <= 0) {throw new RuntimeException("无效金额");}}
}
4.3 数据库支持
全局事务表
Seata 需要一张 global_table
存储全局事务信息。SQL 示例:
CREATE TABLE global_table (xid VARCHAR(128) NOT NULL,transaction_id BIGINT,status TINYINT,gmt_create TIMESTAMP,gmt_modified TIMESTAMP,PRIMARY KEY (xid)
);
回滚日志表
Seata 的 AT 模式需要存储回滚日志:
CREATE TABLE undo_log (id BIGINT AUTO_INCREMENT,branch_id BIGINT NOT NULL,xid VARCHAR(128) NOT NULL,rollback_info LONGTEXT NOT NULL,log_status INT NOT NULL,log_created TIMESTAMP NOT NULL,log_modified TIMESTAMP NOT NULL,PRIMARY KEY (id)
);
5. 运行与测试
测试步骤
- 启动 Seata Server 和相关服务(Nacos、数据库)。
- 运行 Spring Boot 项目。
- 模拟事务成功:
- 创建订单,扣减库存,扣款。
- 模拟事务失败:
- 在事务中抛出异常,观察全局回滚。
6. 常见问题与优化
常见问题
-
事务未回滚:
- 检查
@GlobalTransactional
是否正确配置。 - 确保 Seata Server 正常运行。
- 检查
-
性能问题:
- AT 模式适合高性能场景,但需要占用更多数据库资源。
- 在性能要求较高的场景中,优先选择 TCC 模式。
优化建议
- 连接池配置:
- 使用 HikariCP 提升数据库连接性能。
- 分库分表支持:
- 在分库分表场景中,使用 Seata 结合 ShardingSphere。
7. Seata 与其他分布式事务框架对比
特性 | Seata | TCC | SAGA | XA |
---|---|---|---|---|
易用性 | 高 | 中 | 中 | 低 |
性能 | 高(AT) | 高 | 中 | 低 |
适用场景 | 电商、金融 | 自定义事务 | 长事务 | 强一致性 |
事务隔离 | 强 | 中 | 中 | 强 |
总结
Seata 提供了多种事务模型,能够高效处理分布式事务问题,特别适合微服务架构下的复杂场景。