Seata的 TCC 模式

目录

概述

使用

依赖与配置

代码


概述

   TCC 模式是一种侵入式的分布式事务解决方案,它不依赖于数据库的事务,而是要求开发者自定义完成 预提交、提交、回滚的方法逻辑。因此,它是一个种偏 复杂、灵活、有侵入性 的分布式事务处理方案。

 Demo

   这里附上seata的学习代码demo,开箱即用。包含AT/TCC/XA等模式的使用案例https://download.csdn.net/download/lmj3732018/88864802

使用

依赖与配置

    Seata的TCC模式依赖和配置与AT模式完全一致,只是TCC模式不需要定义 undo_log 数据库表,这里不再赘述。

代码

    1. 在使用时,我们需要在多个本地事务分支的外层使用 @GlobalTransactional 开启全局事务

@Override
@GlobalTransactional(name="createOrder",rollbackFor=Exception.class)
public Order saveOrder(OrderVo orderVo) {
    log.info("=============用户下单=================");
    log.info("当前 XID: {}", RootContext.getXID());
 
    //获取全局唯一订单号  测试使用
    Long orderId = UUIDGenerator.generateUUID();
 
    //阶段一: 创建订单
    Order order = orderService.prepareSaveOrder(orderVo,orderId);
 
    //扣减库存
    storageFeignService.deduct(orderVo.getCommodityCode(), orderVo.getCount());
    //扣减余额
    accountFeignService.debit(orderVo.getUserId(), orderVo.getMoney());
 
    return order;
}

2. 定义各个本地事务分支的预提交、提交、回滚方法

OrderService 接口

/**
 *
 * 通过 @LocalTCC 这个注解,RM 初始化的时候会向 TC 注册一个分支事务。
 */
@LocalTCC
public interface OrderService {
 
    /**
     * TCC的try方法:保存订单信息,状态为支付中
     *
     * 定义两阶段提交,在try阶段通过@TwoPhaseBusinessAction注解定义了分支事务的 resourceId,commit和 cancel 方法
     *  name = 该tcc的bean名称,全局唯一
     *  commitMethod = commit 为二阶段确认方法
     *  rollbackMethod = rollback 为二阶段取消方法
     *  BusinessActionContextParameter注解 传递参数到二阶段中
     *  useTCCFence seata1.5.1的新特性,用于解决TCC幂等,悬挂,空回滚问题,需增加日志表tcc_fence_log
     */
    @TwoPhaseBusinessAction(name = "prepareSaveOrder", commitMethod = "commit", rollbackMethod = "rollback", useTCCFence = true)
    Order prepareSaveOrder(OrderVo orderVo, @BusinessActionContextParameter(paramName = "orderId") Long orderId);
 
    /**
     *
     * TCC的confirm方法:订单状态改为支付成功
     *
     * 二阶段确认方法可以另命名,但要保证与commitMethod一致
     * context可以传递try方法的参数
     *
     * @param actionContext
     * @return
     */
    boolean commit(BusinessActionContext actionContext);
 
    /**
     * TCC的cancel方法:订单状态改为支付失败
     * 二阶段取消方法可以另命名,但要保证与rollbackMethod一致
     *
     * @param actionContext
     * @return
     */
    boolean rollback(BusinessActionContext actionContext);
}

OrderServiceImpl实现类

@Service
@Slf4j
public class OrderServiceImpl implements OrderService {
 
    @Autowired
    private OrderMapper orderMapper;
 
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Order prepareSaveOrder(OrderVo orderVo,
                                  @BusinessActionContextParameter(paramName = "orderId") Long orderId) {
 
        // 保存订单
        Order order = new Order();
        order.setId(orderId);
        order.setUserId(orderVo.getUserId());
        order.setCommodityCode(orderVo.getCommodityCode());
        order.setCount(orderVo.getCount());
        order.setMoney(orderVo.getMoney());
        order.setStatus(OrderStatus.INIT.getValue());
        Integer saveOrderRecord = orderMapper.insert(order);
        log.info("保存订单{}", saveOrderRecord > 0 ? "成功" : "失败");
 
        return order;
    }
 
    @Override
    public boolean commit(BusinessActionContext actionContext) {
 
 
        // 获取订单id
        long orderId = Long.parseLong(actionContext.getActionContext("orderId").toString());
        //更新订单状态为支付成功
        Integer updateOrderRecord = orderMapper.updateOrderStatus(orderId, OrderStatus.SUCCESS.getValue());
        log.info("更新订单id:{} {}", orderId, updateOrderRecord > 0 ? "成功" : "失败");
 
        return true;
    }
 
    @Override
    public boolean rollback(BusinessActionContext actionContext) {
 
        //获取订单id
        long orderId = Long.parseLong(actionContext.getActionContext("orderId").toString());
        //更新订单状态为支付失败
        Integer updateOrderRecord = orderMapper.updateOrderStatus(orderId, OrderStatus.FAIL.getValue());
        log.info("更新订单id:{} {}", orderId, updateOrderRecord > 0 ? "成功" : "失败");
 
        return true;
    }
 
 
}

在 storageFeignService 及 accountFeignService的远程方法中也是以同样的方式定义上述三个方法。

  • 8
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

季风泯灭的季节

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值