分布式事务补偿机制中的事务状态管理踩坑记录
最近在设计一个分布式订单系统时,遇到了事务状态管理的坑,分享一下踩坑过程。
问题背景
系统采用TCC模式,涉及订单、库存、账户三个服务。在测试过程中发现,当库存服务调用失败后,补偿机制无法正确回滚已执行的操作。
复现步骤
- 创建订单并扣减库存
- 库存服务抛出异常
- 调用补偿接口进行回滚
- 发现事务状态混乱
核心代码问题
public class CompensationService {
@Transactional
public void compensateOrder(String orderId) {
// 状态更新逻辑有问题
orderMapper.updateStatus(orderId, "COMPENSATED");
// 业务补偿逻辑
inventoryService.refundInventory(orderId);
}
}
坑点分析
- 事务状态未正确管理:补偿前后的状态变更没有原子性保障
- 重试机制缺失:补偿失败后没有重试策略
- 状态机设计缺陷:缺少完整的事务状态流转图
解决方案
public class ImprovedCompensationService {
@Transactional
public void compensateOrder(String orderId) {
// 先检查状态,确保可补偿
Order order = orderMapper.selectById(orderId);
if (order.getStatus() != "FAILED") {
throw new RuntimeException("订单状态不可补偿");
}
// 记录补偿日志
compensationLogMapper.insert(new CompensationLog(orderId, "STARTED"));
try {
inventoryService.refundInventory(orderId);
orderMapper.updateStatus(orderId, "COMPENSATED");
compensationLogMapper.updateStatus(orderId, "SUCCESS");
} catch (Exception e) {
// 补偿失败,记录错误
compensationLogMapper.updateStatus(orderId, "FAILED");
throw e;
}
}
}
经验总结
- 状态管理必须原子化
- 增加补偿日志追踪
- 完善异常处理和重试机制

讨论