分布式事务之TCC

业务场景介绍

假设现在有一个电商系统,里面有一个支付订单的场景。
在这里插入图片描述
对一个订单进行支付之后,我们需要做下面的步骤:

  • 更改订单的状态为“已支付”
  • 扣减商品库存
  • 给会员增加积分
  • 创建销售出库单通知仓库发货

以上业务场景对应下面的代码:

public class OrderService {

    // 库存服务
    @Autowired
    private InventoryService inventoryService;

    // 积分服务
    @Autowired
    private CreditService creditService;

    // 仓储服务
    @Autowired
    private WmsService wmsService;

    // 对这个订单完成支付
    public void pay(){
        //对本地的的订单数据库修改订单状态为"已支付"
        orderDAO.updateStatus(OrderStatus.PAYED);

        //调用库存服务扣减库存
        inventoryService.reduceStock();

        //调用积分服务增加积分
        creditService.addCredit();

        //调用仓储服务通知发货
        wmsService.saleDelivery();
    }
}

补偿事务:TCC

TCC是Try-Confirm-Cancel的简称:

Try 阶段:尝试执行,完成所有业务检查(一致性),预留必需业务资源(准隔离性)。

Confirm 阶段:确认真正执行业务,不作任何业务检查,只使用 Try 阶段预留的业务资源,Confirm 操作满足幂等性。要求具备幂等设计,Confirm 失败后需要进行重试。

Cancel 阶段:取消执行,释放 Try 阶段预留的业务资源,Cancel 操作满足幂等性。Cancel 阶段的异常和 Confirm 阶段异常处理方案基本上一致。

Try阶段

在这里插入图片描述

Confirm阶段

在这里插入图片描述

Cancle阶段

在这里插入图片描述

总结与思考

总结一下,你要玩 TCC 分布式事务的话:首先需要选择某种 TCC 分布式事务框架,各个服务里就会有这个 TCC 分布式事务框架在运行。

然后原本的一个接口,要改造为 3 个逻辑,Try-Confirm-Cancel:

  1. 先是服务调用链路依次执行 Try 逻辑。
  2. 如果都正常的话,TCC 分布式事务框架推进执行 Confirm 逻辑,完成整个事务。
  3. 如果某个服务的 Try 逻辑有问题,TCC 分布式事务框架感知到之后就会推进执行各个服务的 Cancel 逻辑,撤销之前执行的各种操作。

问题1:如果有一些意外的情况发生了,比如说订单服务突然挂了,然后再次重启,TCC 分布式事务框架是如何保证之前没执行完的分布式事务继续执行的呢?
所以,TCC 事务框架都是要记录一些分布式事务的活动日志的,可以在磁盘上的日志文件里记录,也可以在数据库里记录。保存下来分布式事务运行的各个阶段和状态。

问题2:万一某个服务的 Cancel 或者 Confirm 逻辑执行一直失败怎么办呢?
TCC 事务框架会通过活动日志记录各个服务的状态。举个例子,比如发现某个服务的 Cancel 或者 Confirm 一直没成功,会不停的重试调用它的 Cancel 或者 Confirm 逻辑,务必要它成功!


给大家推荐几个比较不错的框架,都是国内开源的:ByteTCC,TCC-transaction,Himly。

大家有兴趣的可以去它们的 GitHub 地址,学习一下如何使用,以及如何跟 Spring Cloud、Dubbo 等服务框架整合使用。

### Seata 分布式事务 TCC 模式的使用方法 #### 配置前提条件 为了在Seata中启用TCC模式,首先需要完成类似于AT模式的基础配置工作。这包括但不限于设置全局事务管理器地址、注册微服务到Nacos等操作[^3]。 #### 实现TCC接口逻辑 TCC模式的核心在于定义三个主要的操作:`try`, `confirm` 和 `cancel` 方法。这些方法分别对应着尝试执行业务活动、确认提交以及取消操作的行为。对于每一个参与分布式事务的服务端点而言,都需要实现这三个阶段的方法: - **Try**: 尝试执行业务逻辑,在这个过程中可能会预留资源或检查约束条件。 - **Confirm**: 如果所有参与者都成功完成了各自的Try阶段,则会触发Confirm过程,正式生效之前所做的准备动作。 - **Cancel**: 当任意一个节点上的Try失败时,其他已经成功的Try将会被回滚,即调用Cancel函数释放已占用的资源。 ```java public interface OrderService { /** * Try phase of the order service. */ void tryCreateOrder(); /** * Confirm phase of the order service, which commits changes made during the try phase. */ void confirmCreateOrder(); /** * Cancel phase of the order service, used to undo any effects from a failed transaction attempt. */ void cancelCreateOrder(); } ``` 需要注意的是,在实际开发环境中,上述每个方法的具体行为取决于具体的业务场景和所使用的存储介质特性[^1]。 #### 处理数据一致性与隔离级别 由于TCC本身并不提供默认的数据隔离性保障,因此开发者需自行处理好并发控制问题以确保数据的一致性和准确性。通常情况下,可以通过加锁或其他同步手段来防止竞态条件的发生。此外,虽然单个数据库内部可以依靠其自身的ACID属性维持局部范围内的事务完整性,但在跨多个独立系统的分布式架构里,整体一致性的维护则更加复杂,往往依赖于精心设计的应用层协议来达成目标[^4]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值