spring seate实战2pc、3pc、tcc、saga。
seate实战tcc
TCC(Try-Confirm-Cancel)是一种用于解决分布式事务问题的设计模式,它通过将一个复杂的分布式事务拆分成三个阶段来实现:
Try阶段:尝试执行所有操作,并将所有修改记录在本地事务日志中。
Confirm阶段:所有操作都已成功执行,向分布式协调器发送确认请求,并将本地事务日志标记为“已提交”。
Cancel阶段:有任何一个操作执行失败,向分布式协调器发送回滚请求,并将本地事务日志标记为“已回滚”。
以下是使用Seata实现TCC模式的示例代码:
首先需要在代码中引入Seata相关依赖,同2PC。
在启动类中配置Seata的相关参数,同2PC。
使用@TwoPhaseBusinessAction注解来标记每个TCC事务的每个阶段方法,并在第一个阶段的方法中调用TCC上下文来记录操作信息。同时,使用@GlobalTransactional注解来标记整个TCC事务的开始方法:
@Service
public class OrderServiceImpl implements OrderService {
@Autowired
private OrderMapper orderMapper;
@Autowired
private ProductServiceFeignClient productServiceFeignClient;
@Autowired
private AccountServiceFeignClient accountServiceFeignClient;
@GlobalTransactional(timeoutMills = 300000, name = "order-service-tcc")
@Override
public String createOrder(OrderDTO orderDTO) {
orderMapper.createOrder(orderDTO);
try {
productServiceFeignClient.tryReduceStock(orderDTO.getProductId(), orderDTO.getAmount());
accountServiceFeignClient.tryReduceBalance(orderDTO.getUserId(), orderDTO.getTotalPrice());
SeataTccContextUtils.getCurrentContext().set("status", "T");
} catch (Exception e) {
SeataTccContextUtils.getCurrentContext().set("status", "F");
throw e;
}
return orderDTO.getId();
}
@TwoPhaseBusinessAction(name = "order-service-reduce-stock-tcc", commitMethod = "commitReduceStock", rollbackMethod = "rollbackReduceStock")
@Override
public boolean tryReduceStock(Long productId, Integer amount) {
productServiceFeignClient.tryReduceStock(productId, amount);
return true;
}
public boolean commitReduceStock(Long productId, Integer amount) {
productServiceFeignClient.confirmReduceStock(productId, amount);
return true;
}
public boolean rollbackReduceStock(Long productId, Integer amount) {
productServiceFeignClient.cancelReduceStock(productId, amount);
return true;
}
@TwoPhaseBusinessAction(name = "order-service-reduce-balance-tcc", commitMethod = "commitReduceBalance", rollbackMethod = "rollbackReduceBalance")
@Override
public boolean tryReduceBalance(Long userId, BigDecimal amount) {
accountServiceFeignClient.tryReduceBalance(userId, amount);
return true;
}
public boolean commitReduceBalance(Long userId, BigDecimal amount) {
accountServiceFeignClient.confirmReduceBalance(userId, amount);
return true;
}
public boolean rollbackReduceBalance(Long userId, BigDecimal amount) {
accountServiceFeignClient.cancelReduceBalance(userId, amount);
return true;
}
}
在这个示例代码中,使用@GlobalTransactional注解来标记整个TCC事务的开始方法createOrder,并在try阶段的方法中记录操作状态,即如果所有操作都执行成功,则将状态设置为“T”,否则设置为“F”。在commit和rollback阶段的方法中,分别调用Feign客户端来发送确认和取消请求。
在Feign客户端中,也需要使用@TwoPhaseBusinessAction注解来标记TCC事务的每个阶段方法,并在try阶段的方法中将操作信息记录在TCC上下文中:
@FeignClient(name = "product-service")
public interface ProductServiceFeignClient {
@TwoPhaseBusinessAction(name = "product-service-reduce-stock-tcc", commitMethod = "commitReduceStock", rollbackMethod = "rollbackReduceStock")
@RequestMapping("/product/reduceStock")
boolean tryReduceStock(@RequestParam("productId") Long productId, @RequestParam("amount") Integer amount);
@RequestMapping("/product/confirmReduceStock")
boolean commitReduceStock(@RequestParam("productId") Long productId, @RequestParam("amount") Integer amount);
@RequestMapping("/product/cancelReduceStock")
boolean rollbackReduceStock(@RequestParam("productId") Long productId, @RequestParam("amount") Integer amount);
}
在这个示例代码中,使用@TwoPhaseBusinessAction注解来标记TCC事务的每个阶段方法,并在try阶段的方法中将操作信息记录在TCC上下文中。
同样地,在AccountServiceFeignClient中也需要使用@TwoPhaseBusinessAction注解来标记TCC事务的每个阶段方法,并在try阶段的方法中将操作信息记录在TCC上下文中:
@FeignClient(name = "account-service")
public interface AccountServiceFeignClient {
@TwoPhaseBusinessAction(name = "account-service-reduce-balance-tcc", commitMethod = "commitReduceBalance", rollbackMethod = "rollbackReduceBalance")
@RequestMapping("/account/reduceBalance")
boolean tryReduceBalance(@RequestParam("userId") Long userId, @RequestParam("amount") BigDecimal amount);
@RequestMapping("/account/confirmReduceBalance")
boolean commitReduceBalance(@RequestParam("userId") Long userId, @RequestParam("amount") BigDecimal amount);
@RequestMapping("/account/cancelReduceBalance")
boolean rollbackReduceBalance(@RequestParam("userId") Long userId, @RequestParam("amount") BigDecimal amount);
}
在这个示例代码中,也是使用@TwoPhaseBusinessAction注解来标记TCC事务的每个阶段方法,并在try阶段的方法中将操作信息记录在TCC上下文中。
TCC模式的优点在于,它将分布式事务拆分为三个阶段,可以更细粒度地控制事务的执行,避免锁定资源和长时间阻塞。但是,TCC模式的实现相对复杂,需要手动编写大量的代码来处理各种异常情况,同时需要在应用程序中保持状态一致性,因此需要更多的开发工作和测试工作。