官网案例
https://seata.io/zh-cn/docs/dev/mode/tcc-mode.html
TCC模式
TCC是Try、Confirm、Cancel三个词语的缩写,TCC要求每个分支事务实现三个操作 :预处理Try、确认Confirm、撤销Cancel。Try操作做业务检查及资源预留,Confirm做业务确认操作,Cancel实现一个与Try相反的操作既回滚操作。TM首先发起所有的分支事务的try操作,任何一个分支事务的try操作执行失败,TM将会发起所有分支事务的Cancel操作,若try操作全部成功,TM将会发起所有分支事务的Confirm操作,其中Confirm/Cancel操作若执行失败,TM会进行重试。
TCC需要注意三种异常处理分别是空回滚、幂等、悬挂 :
由于自己编写业务,所以TCC模式可以对redis分布式事务也进行管理,另外TCC只适用于数值类业务回滚(因为要冻结数值类进行加减运算)
基本没有锁的概念,性能更强
案例
https://blog.csdn.net/wjw465150/article/details/127004209
OrderController
编写接口,并开启全局事务,对外提供测试
@RestController
public class OrderController {
@GlobalTransactional
@PostMapping("/consumer/order/createOrder")
public ResEntity createOrder() {
LockOrder o = new LockOrder();
tccOrderService.insert(o);
return Res.ok();
}
OrderService 业务接口
@LocalTCC 注解在业务接口上,只要实现了TCC的两阶段提交对应方法便可,适用于SpringCloud+Feign模式下的TCC。
@LocalTCC
public interface OrderService {
@TwoPhaseBusinessAction(name="insert", commitMethod = "commitTcc", rollbackMethod = "cancel")
public boolean insert(@BusinessActionContextParameter(paramName = "lockOrder")LockOrder lockOrder);
public boolean commitTcc(BusinessActionContext context);
public boolean cancel(BusinessActionContext context);
}
OrderServiceImpl 业务实现类
orderFeignService 调用远程服务,创建订单。
@Service
public class OrderServiceImpl implements OrderService {
@Resource
private SeataOrderFeignService seataOrderFeignService;
@Transactional
public boolean insert(LockOrder lockOrder) {
order.setSerialNumber(UuidUtil.getOrderSN());
order.setCreateTime(new Date());
orderMapper.insertSelective(order);
//
ResEntity result = seataOrderFeignService.createOrder(1L);
log.info("TCC result " + result);
if(Res.isFailed(result)){
throw new RuntimeException(""+ result);
}
log.info("TCC order create success");
return true;
}
@Override
public boolean commitTcc(BusinessActionContext context) {
log.info("commit----------> context xid = " + context.getXid());
return true;
}
@Override
public boolean cancel(BusinessActionContext context) {
log.info("cancel----------> context xid = " + context.getXid());
return true;
}}
说明
@LocalTCC 注解在业务接口上,只要实现了TCC的两阶段提交对应方法便可,适用于SpringCloud+Feign模式下的TCC。
@TwoPhaseBusinessAction:注解try方法,其中name为当前tcc方法的bean名称,写方法名便可(全局唯一),
commitMethod指向提交方法,
rollbackMethod指向事务回滚方法。指定好三个方法之后,seata会根据全局事务的成功或失败,自动调用提交方法或者回滚方法。
@BusinessActionContextParameter:使用该注解可以将参数传递到二阶段commit或者rollback的方法中,方便调用。
BusinessActionContext: TCC事务上下文,使用BusinessActionContext.getActionContext("params")便可以得到一阶段try中定义的参数,在二阶段参考此参数进行业务回滚操作。
建议:可以在try方法中使用@Transational,直接通过spring来控制关系型数据库的事务,进行回滚的操作,而非关系型数据库等中间件的回滚操作可以交给rollbackMethod方法处理。
建议:try接口不可以捕获异常,否则TCC将识别该操作为成功,直接执行二阶段commit方法。