Seata TCC模式开发指南
2025/9/17大约 3 分钟
Seata TCC模式开发指南
前置知识
在学习本教程之前,请确保您已经:
- 了解Seata的基本概念
- 掌握Spring Boot和Spring Cloud开发
- 理解TCC事务理论
TCC模式简介
TCC(Try-Confirm-Cancel)是一种补偿型分布式事务解决方案,它将一个完整的业务分成三个阶段:
- Try:尝试执行,完成业务检查和资源预留
- Confirm:确认执行,完成资源占用
- Cancel:取消执行,释放预留资源
优势与特点
- 业务灵活性高:可以根据业务需求自定义事务逻辑
- 隔离性较好:资源预留机制避免了资源争用
- 性能较好:不依赖数据库事务,无需生成UNDO LOG
接口设计
1. TCC接口定义
@LocalTCC
public interface OrderService {
@TwoPhaseBusinessAction(name = "createOrder", commitMethod = "confirm", rollbackMethod = "cancel")
boolean try(BusinessActionContext actionContext, @BusinessActionContextParameter(paramName = "order") Order order);
boolean confirm(BusinessActionContext actionContext);
boolean cancel(BusinessActionContext actionContext);
}
2. 实现类
@Service
@Slf4j
public class OrderServiceImpl implements OrderService {
@Autowired
private OrderMapper orderMapper;
@Override
public boolean try(BusinessActionContext actionContext, Order order) {
// 1. 校验订单
if (order == null || order.getAmount() <= 0) {
throw new RuntimeException("订单数据异常");
}
// 2. 预留资源(冻结库存)
order.setStatus(OrderStatus.TRY.getCode());
orderMapper.insert(order);
// 3. 保存上下文数据
actionContext.addActionContext("orderId", order.getId());
return true;
}
@Override
public boolean confirm(BusinessActionContext actionContext) {
// 1. 获取上下文数据
Long orderId = (Long) actionContext.getActionContext("orderId");
// 2. 确认订单
Order order = orderMapper.selectById(orderId);
order.setStatus(OrderStatus.CONFIRM.getCode());
orderMapper.updateById(order);
return true;
}
@Override
public boolean cancel(BusinessActionContext actionContext) {
// 1. 获取上下文数据
Long orderId = (Long) actionContext.getActionContext("orderId");
// 2. 取消订单
Order order = orderMapper.selectById(orderId);
order.setStatus(OrderStatus.CANCEL.getCode());
orderMapper.updateById(order);
return true;
}
}
异常处理
1. 幂等性处理
注意事项
TCC的每个阶段都必须实现幂等性,以应对网络超时和重试场景。
@Service
public class OrderServiceImpl implements OrderService {
@Override
public boolean confirm(BusinessActionContext actionContext) {
Long orderId = (Long) actionContext.getActionContext("orderId");
Order order = orderMapper.selectById(orderId);
// 幂等性检查
if (OrderStatus.CONFIRM.getCode().equals(order.getStatus())) {
return true;
}
// 执行确认逻辑
order.setStatus(OrderStatus.CONFIRM.getCode());
orderMapper.updateById(order);
return true;
}
}
2. 空回滚处理
说明
空回滚是指Try未执行,直接执行了Cancel的情况。
@Override
public boolean cancel(BusinessActionContext actionContext) {
Long orderId = (Long) actionContext.getActionContext("orderId");
// 空回滚处理
if (orderId == null) {
return true;
}
Order order = orderMapper.selectById(orderId);
if (order == null) {
return true;
}
// 执行取消逻辑
order.setStatus(OrderStatus.CANCEL.getCode());
orderMapper.updateById(order);
return true;
}
最佳实践
设计建议
实践要点
- 资源预留:Try阶段要预留充足的资源
- 防悬挂:处理空回滚和业务悬挂
- 状态机制:维护清晰的事务状态
- 超时控制:合理设置事务超时时间
代码优化
@Data
@Builder
public class TccContext {
private String xid;
private Long orderId;
private Integer status;
private LocalDateTime createTime;
public static TccContext from(BusinessActionContext context) {
return TccContext.builder()
.xid(context.getXid())
.orderId((Long) context.getActionContext("orderId"))
.createTime(LocalDateTime.now())
.build();
}
}
常见问题
1. TCC模式如何保证事务一致性?
TCC通过以下机制保证一致性:
- Try阶段预留资源
- Confirm/Cancel阶段的幂等性设计
- 事务状态记录和超时处理
- 防悬挂设计
2. 如何处理TCC事务超时?
@GlobalTransactional(timeoutMills = 60000)
public void businessMethod() {
// 设置合理的超时时间
orderService.try(context, order);
}
超时处理建议:
- 设置合适的超时时间
- 实现重试机制
- 记录事务日志
总结
本文详细介绍了Seata TCC模式的实现方法:
- ✅ 基本概念:Try-Confirm-Cancel三个阶段
- ✅ 接口设计:TCC接口定义和实现
- ✅ 异常处理:幂等性和空回滚
- ✅ 最佳实践:设计建议和代码优化
- ✅ 常见问题:一致性保证和超时处理
下一步学习
- 了解Saga模式的实现原理
- 学习XA模式的使用场景
- 探索混合模式的应用