一、为什么需要Seata?
在微服务架构中,跨服务的事务管理成为核心痛点:
- 传统事务失效:服务拆分导致无法使用本地事务
- 数据不一致风险:网络抖动、服务宕机等情况导致数据错乱
- 复杂场景处理难:涉及多个数据库、消息队列等异构存储
Seata(Simple Extensible Autonomous Transaction Architecture) 是阿里开源的分布式事务解决方案,提供 AT模式、TCC模式、Saga模式 三种事务模型,支持高并发场景下的数据一致性。
二、核心概念与架构原理
2.1 核心角色
角色 | 说明 |
---|---|
TC (Transaction Coordinator) | 事务协调器,维护全局事务状态(需独立部署) |
TM (Transaction Manager) | 事务管理器,定义事务边界(@GlobalTransactional注解) |
RM (Resource Manager) | 资源管理器,管理分支事务(连接数据库等资源) |
2.2 AT模式核心原理
执行流程:
数据回滚机制:
- 阶段一:执行业务SQL,保存前置镜像(before image)和后置镜像(after image)
- 阶段二:
- 提交:异步删除快照数据
- 回滚:用前置镜像还原数据
三、环境搭建与配置(Spring Cloud Alibaba版)
3.1 组件版本
组件 | 版本 |
---|---|
Spring Boot | 2.6.11 |
Spring Cloud | 2021.0.4 |
Spring Cloud Alibaba | 2021.0.4.0 |
Seata Server | 1.7.0 |
3.2 Seata Server部署
# 下载并解压
wget https://github.com/seata/seata/releases/download/v1.7.0/seata-server-1.7.0.zip
unzip seata-server-1.7.0.zip# 修改配置文件 conf/registry.conf
registry {type = "nacos"nacos {serverAddr = "localhost:8848"namespace = ""cluster = "default"}
}# 启动服务端
sh bin/seata-server.sh -p 8091 -h 127.0.0.1
四、SpringBoot整合AT模式实战
4.1 订单服务配置
pom.xml:
<dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-seata</artifactId>
</dependency>
application.yml:
spring:cloud:alibaba:seata:tx-service-group: my_tx_group # 事务组名称seata:registry:type: nacosnacos:server-addr: localhost:8848service:vgroup-mapping:my_tx_group: default # 对应TC集群
4.2 业务代码示例
订单服务(扣减库存):
@Service
public class OrderServiceImpl implements OrderService {@Autowiredprivate StorageFeignClient storageFeignClient;@GlobalTransactional // 开启全局事务@Overridepublic void createOrder(OrderDTO orderDTO) {// 1. 本地事务:创建订单orderMapper.create(orderDTO);// 2. 远程调用:扣减库存storageFeignClient.deduct(orderDTO.getProductId(), orderDTO.getCount());// 测试回滚// int i = 1/0; }
}
库存服务(Feign接口):
@FeignClient(name = "storage-service")
public interface StorageFeignClient {@PostMapping("/storage/deduct")void deduct(@RequestParam("productId") Long productId, @RequestParam("count") Integer count);
}
五、TCC模式实战(适合高并发场景)
5.1 TCC核心概念
- Try:预留资源(如冻结库存)
- Confirm:确认操作(真正扣减)
- Cancel:回滚操作(释放资源)
5.2 库存服务实现
TCC接口定义:
public interface StorageTccService {@TwoPhaseBusinessAction(name = "deduct", commitMethod = "confirm", rollbackMethod = "cancel")boolean tryDeduct(@BusinessActionContextParameter(paramName = "productId") Long productId,@BusinessActionContextParameter(paramName = "count") Integer count);boolean confirm(BusinessActionContext context);boolean cancel(BusinessActionContext context);
}
Try阶段实现:
@Override
public boolean tryDeduct(Long productId, Integer count) {// 冻结库存(非实际扣减)storageMapper.freezeStock(productId, count);return true;
}
Cancel阶段实现:
@Override
public boolean cancel(BusinessActionContext context) {Long productId = Long.valueOf(context.getActionContext("productId").toString());Integer count = Integer.valueOf(context.getActionContext("count").toString());// 释放冻结库存storageMapper.unfreezeStock(productId, count);return true;
}
六、常见问题解决方案
6.1 TC服务无法注册到Nacos
- 检查Nacos服务是否正常启动
- 确认registry.conf配置的namespace与Nacos一致
- 查看seata-server启动日志是否有连接错误
6.2 全局事务不生效
- 确认@GlobalTransactional注解添加正确
- 检查spring-cloud-alibaba-seata依赖版本
- 查看TM和RM是否使用相同的事务组配置
6.3 脏数据回滚失败
- 检查undo_log表是否自动创建
- 确认数据库用户有权限操作undo_log表
- 验证AT模式下的SQL是否符合要求(必须有主键)
七、生产环境最佳实践
-
TC服务高可用:
- 部署至少3个TC节点
- 使用Nacos集群做服务发现
-
数据持久化配置:
# conf/file.conf
store {mode = "db"db {datasource = "druid"dbType = "mysql"url = "jdbc:mysql://127.0.0.1:3306/seata"user = "root"password = "123456"}
}
- 监控告警:
- 集成Prometheus监控事务成功率
- 配置事务超时时间(默认60秒)
八、源码解析(理解核心机制)
关键类说明:
类名 | 作用 |
---|---|
DefaultCoordinator | 事务协调核心逻辑 |
GlobalTransactionScanner | 扫描@GlobalTransactional注解 |
AsyncWorker | 异步处理分支提交/回滚 |
UndoLogManager | 管理数据快照 |
事务提交源码片段:
public void commit() {// 异步执行提交AsyncCallback<Boolean> callback = new AsyncCallback<Boolean>() {@Overridepublic void onSuccess(Boolean result) {// 删除undo logundoLogManager.deleteUndoLog(xid, branchId);}};asyncWorker.branchCommit(branchType, xid, branchId, callback);
}