在分布式系统中,事务数据完整性校验是补偿机制的核心环节。本文通过对比两种常见的校验方案来验证其实际效果。
问题背景:某电商系统采用TCC模式处理订单支付,在执行补偿时需要确保数据一致性。
方案对比:
- 基于版本号的校验(推荐)
public class OrderService {
@Transactional
public void processPayment(String orderId) {
// 更新订单状态并记录版本号
Order order = orderRepository.findById(orderId);
order.setVersion(order.getVersion() + 1);
order.setStatus("PAYMENT_PROCESSING");
orderRepository.save(order);
// 执行支付操作
paymentService.pay(orderId);
}
public void compensate(String orderId) {
Order order = orderRepository.findById(orderId);
// 校验版本号是否一致
if (order.getVersion() != expectedVersion) {
throw new RuntimeException("数据已被修改,无法补偿");
}
paymentService.refund(orderId);
}
}
- 基于状态机的校验
public class StateValidator {
private static final Set<String> ALLOWED_STATES = Set.of("PAYMENT_PENDING", "PAYMENT_SUCCESS");
public boolean validateCompensation(String orderId) {
Order order = orderRepository.findById(orderId);
return ALLOWED_STATES.contains(order.getStatus());
}
}
实测对比:
- 版本号方案:在并发修改场景下能有效防止脏写,但性能开销略大
- 状态机方案:性能好但无法防范并发修改问题
结论:建议采用版本号校验+状态检查的双重保障机制,既保证数据完整性又兼顾性能。
可复现步骤:
- 启动两个服务实例
- 同时对同一订单进行支付操作
- 观察补偿机制如何处理并发冲突
- 验证版本号校验是否生效

讨论