Seata实战:AT/TCC/SAGA模式详解与微服务集成指南
Seata实战指南:AT/TCC/SAGA模式详解与微服务集成
一、AT模式使用:自动补偿型事务
1. 快速接入
在Spring Boot项目中引入依赖:
<dependency>
<groupId>io.seata</groupId>
<artifactId>seata-spring-boot-starter</artifactId>
<version>最新版本</version>
</dependency>
2. 关键配置示例
seata:
enabled: true
application-id: order-service
tx-service-group: my_tx_group # 事务分组需与seata-server配置匹配
service:
vgroup-mapping:
my_tx_group: default # 映射到Seata Server集群
config:
type: nacos # 配置中心类型
registry:
type: nacos # 注册中心类型
store:
mode: db # 事务日志存储模式(可选file/db/redis)
3. 业务代码示例
@Service
public class OrderService {
@GlobalTransactional(timeoutMills = 300000, name = "createOrder")
public void createOrder(OrderDTO order) {
// 1. 扣减库存
stockFeignClient.deduct(order.getProductId(), order.getCount());
// 2. 创建订单
orderMapper.insert(order);
// 3. 扣减账户余额
accountFeignClient.debit(order.getUserId(), order.getMoney());
}
}
实践建议:
- 事务超时时间根据业务复杂度合理设置
- 事务分组名称建议按业务领域划分
- 生产环境推荐使用DB存储模式保证可靠性
二、TCC模式实现:精细化控制
1. 接口定义规范
@LocalTCC
public interface AccountService {
@TwoPhaseBusinessAction(name = "deduct", commitMethod = "confirm", rollbackMethod = "cancel")
boolean tryDeduct(@BusinessActionContextParameter(paramName = "userId") String userId,
@BusinessActionContextParameter(paramName = "money") BigDecimal money);
boolean confirm(BusinessActionContext context);
boolean cancel(BusinessActionContext context);
}
2. 业务实现要点
@Service
public class AccountServiceImpl implements AccountService {
@Transactional
@Override
public boolean tryDeduct(String userId, BigDecimal money) {
// 检查资源可用性
Account account = accountMapper.selectById(userId);
if (account.getBalance().compareTo(money) < 0) {
throw new RuntimeException("余额不足");
}
// 冻结金额(Try阶段)
account.setFrozen(account.getFrozen().add(money));
accountMapper.updateById(account);
return true;
}
@Override
public boolean confirm(BusinessActionContext context) {
// 实际扣款(Confirm阶段)
String userId = (String) context.getActionContext("userId");
BigDecimal money = (BigDecimal) context.getActionContext("money");
return accountMapper.confirmDeduct(userId, money) > 0;
}
@Override
public boolean cancel(BusinessActionContext context) {
// 释放冻结金额(Cancel阶段)
String userId = (String) context.getActionContext("userId");
BigDecimal money = (BigDecimal) context.getActionContext("money");
return accountMapper.cancelDeduct(userId, money) > 0;
}
}
异常处理机制:
实践建议:
- Try阶段必须实现幂等性
- Confirm/Cancel阶段必须保证成功
- 建议使用
@BusinessActionContextParameter
明确参数映射关系
三、SAGA模式:长事务解决方案
1. 状态机配置示例
{
"Name": "purchaseFlow",
"Steps": [
{
"Name": "reduceInventory",
"Compensate": "compensateInventory",
"ServiceName": "inventoryService",
"ServiceMethod": "reduce"
},
{
"Name": "createOrder",
"Compensate": "compensateOrder",
"ServiceName": "orderService",
"ServiceMethod": "create"
}
]
}
2. 补偿服务实现
@Service
public class InventoryService {
public void reduce(String productId, int count) {
// 扣减库存逻辑
}
public void compensateInventory(String productId, int count) {
// 恢复库存逻辑
System.out.println("执行库存补偿操作");
}
}
执行流程:
实践建议:
- 适用于业务流程长、可接受最终一致性的场景
- 补偿服务必须实现幂等
- 建议每个步骤设置合理的超时时间
四、微服务框架集成
1. Spring Cloud集成要点
@FeignClient(name = "account-service")
public interface AccountFeignClient {
@PostMapping("/account/debit")
Boolean debit(@RequestParam("userId") String userId,
@RequestParam("money") BigDecimal money);
}
// 自动传递XID的RestTemplate配置
@Bean
@LoadBalanced
public RestTemplate restTemplate() {
return new RestTemplate(new SeataRestTemplateInterceptor());
}
2. Dubbo集成配置
# provider端配置
dubbo.provider.filter=seata
# consumer端配置
dubbo.consumer.filter=seata
上下文传递原理:
实践建议:
- 确保微服务间网络可连通
- Dubbo建议使用2.7.0以上版本
- 跨语言调用需手动传递
seata_xid
请求头
五、模式选型指南
特性 | AT模式 | TCC模式 | SAGA模式 |
---|---|---|---|
侵入性 | 低 | 高 | 中 |
一致性 | 强一致 | 最终一致 | 最终一致 |
性能 | 高 | 中 | 中 |
适用场景 | 短事务、CRUD操作 | 需要精确控制的业务 | 长流程、跨系统业务 |
开发复杂度 | 低 | 高 | 中 |
决策建议:
- 优先考虑AT模式,满足大部分业务场景
- 对性能敏感且能接受最终一致性的场景选择SAGA
- 需要精确控制事务边界的业务采用TCC
六、常见问题排查
全局事务不生效检查清单:
- 确认
@GlobalTransactional
注解添加正确 - 检查事务分组配置是否匹配
- 验证Seata Server是否正常运行
- 查看日志中是否有XID传递
- 确认
典型错误日志分析:
// 分支事务注册失败 Could not register branch into global session xid:192.168.1.100:8091:12345678
- 检查undo_log表是否存在
- 验证数据库账号权限
确认TC集群地址配置正确
性能优化参数:
# 客户端配置 client.rm.report.success.enable=false # 关闭分支执行结果上报 client.tm.degrade.check=false # 关闭降级检查 # 服务端配置 store.db.maxWait=5000 # 连接池最大等待时间 server.undo.log.save.days=7 # 缩短undo日志保留时间
评论已关闭