Code前端首页关于Code前端联系我们

PHP轻松完成TCC

terry 2年前 (2023-09-25) 阅读数 49 #后端开发

什么是TCC? TCC 代表“尝试”、“确认”和“取消”。最早由Pat Helland在2007年发表的一篇名为《Life beyond Distributed Transactions:an Apostate’s Opinion》的论文中提出。

TCC组成

TCC分为3个步骤

  • 尝试步骤:尝试执行、完成交易-所有销售验证(一致) 。保存必要的资源(准隔离)
  • 确认计数:如果分支Test成功,则进入Confirm阶段。确认实际执行交易,不进行交易检查,使用测试阶段分配的资源
  • 取消:如果任一分支中的测试之一失败,则转到取消阶段。取消会释放测试阶段分配的资源。

TCC分布式事务中有3个角色s,与普通XA分布式事务类似:

  • AP/Application,发起全局事务,并确定全局事务包括哪些事务实体
  • RM/资源管理器,负责管理分行交易中的各种资源
  • TM/Transaction Manager,负责协调执行全局交易是否正确,包括确认和取消的执行,以及网络异常交易、转账(TransOut)和转账( TransIn)位于不同的微服务中。成功完成TCC交易的典型图如下:

    PHP轻松完成一个分布式事务TCC

    TCC实践

    接下来进行TCC交易定制开发

    目前TCC的开源框架主要是Java语言,以seata为代表。我们的例子使用的是nodejs,使用的分布式事务框架是dtm,它以优雅的方式支持共享。下面详细解释一下TCC的结构,并进行分支调用。

        Dtmcli\tccGlobalTransaction($dtm, function ($tcc) use ($svc) {
            /** @var Dtmcli\Tcc $tcc */
            $req = ['amount' => 30];
            $tcc->callBranch($req, $svc . '/TransOutTry', $svc . '/TransOutConfirm', $svc . '/TransOutCancel');
            $tcc->callBranch($req, $svc . '/TransInTry', $svc . '/TransInConfirm', $svc . '/TransInCancel');
        });
    

    目前已注册完整TCC共享。

    如果你想做一个成功的例子,请看这个例子 yedf/dtmcli-php-sample,运行起来非常简单

    # 部署启动dtm
    # 需要docker版本18以上
    git clone https://github.com/yedf/dtm
    cd dtm
    docker-compose up
    
    # 另起一个命令行
    https://github.com/yedf/dtmcli-php-sample.git
    cd dtmcli-php-sample
    composer install
    php demo.php start

    TCC用户的回滚 2点发现用户2的账户被无效,返回失败。会发生什么?我们可以通过允许 TransIn 重试失败来模拟这种情况,成功的 TCC 意味着当某个子事务返回不成功时,稍后会回滚全局事务。 。对每个子事务调用undo函数,以确保所有全局事务都回滚。

    在TCC交易模式下,很多读者会问,如果Confirm/Cancel失败怎么办?这是一个很好的问题,因为这意味着你正在深入思考 TCC 模型。第一种情况是临时故障,例如网络故障、应用程序或数据库停机。这样的错误会重复,成功最终也会重复;另一种情况是生意失败。根据TCC协议,第一阶段会锁定资源,以保证有足够的资源可以执行Confirm/Cancel。也就是说,从编程逻辑上来说,Confirm/Cancel是不允许重复出厂失败的。如果业务出现故障,那就是bug,开发者需要修复bug。

    总结

    在这篇文章中,我们介绍了TCC的理论知识,并通过实例提供了编写TCC业务的完整流程,涵盖了合法成功的完成和成功退货。相信读者通过本文对TCC有了深入的了解。

版权声明

本文仅代表作者观点,不代表Code前端网立场。
本文系作者Code前端网发表,如需转载,请注明页面地址。

发表评论:

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

热门