zoukankan      html  css  js  c++  java
  • 分布式事务(第05篇)分布式事务解决方法-TCC

    一 什么是TCC

    TCC将每个分支事务都分成三个部分(Try、Confirm、Cancel):

    • Try:业务检查及资源预留。
    • Confirm:真正执行业务,不做任何业务检查。使用Try阶段预留的资源。
    • Cancel:实现回滚操作,释放资源。

    二 TCC实现分布式事务的流程

    1. 第一阶段:全局事务管理器分别调用所有分支事务,所有分支事务进行Try操作,当所有分支事务的Try操作都成功,或者某部分分支事务的Try操作失败,都进入第二阶段。
    2. 第二阶段:如果第一阶段所有分支事务Try都成功执行,则全局事务管理器通知所有分支事务进行Confirm操作,否则,通知所有分支事务进行Cancel操作。

    成功图例:

    失败图例:

    三 举例说明TCC流程

    场景:A账户给B账户转30块,AB在不同的服务。

    方案1:

    A服务:
        Try{
            检查A账户余额是否大于30元。
            A账户扣减30元。
        }
        
        Confirm{
            空。
        }
        
        Cancle{
            A账户增加30元。
        }
    
    B服务:
        Try{
            B账户增加30元。
        }
        
        Confirm{
            空。
        }
        
        Cancle{
            B账户扣减30元。
        }
    

    方案1存在的问题

    1. 由于网络原因,A服务的Try没有执行,分支超时,则全局事务通知所有分支事务进行Cancel,那A账户就多了30元。
    2. Try、Confirm、Cancel都是有单独的线程去执行,且会出现重复调用,不支持幂等性。
    3. B服务执行Try后账户B增加了30元,其他服务将这30元使用了,后因为某种原因AB分支事务需要执行Cancel,B账户就不够30元了。
    4. 与1类型,B服务的Try没有执行,分支超时,则全局事务通知所有分支事务进行Cancel,那B账户就少了30元。

    问题解决

    1. A服务执行Cancel前判断A服务是否执行了Try。
    2. AB服务增加幂等性。
    3. B服务在Confirm中实现增加30元。
    4. B服务执行Cancel前判断B服务是否执行了Try。

    优化后的方案2:

    A服务:
        Try{
            增加幂等性。
            判断是否已经执行了Cancel。若Cancle已执行,则不执行Try,反之则执行Try。
            检查A账户余额是否大于30元。
            A账户扣减30元。
        }
        
        Confirm{
            空。
        }
        
        Cancle{
            增加幂等性。
            判断是否已经执行了Try。若Try未执行,则不执行Cancel,反之则执行Cancel。
            A账户增加30元。
        }
    
    B服务:
        Try{
           空。 
        }
        
        Confirm{
            增加幂等性。
            B账户增加30元。
        }
        
        Cancle{
            空。
        }
    

    由此我们可以发现使用TCC需要注意一些问题。

    四 TCC需要注意的三种异常:

    1. 空回滚
      执行Cancel时需要判断当前分支事务是否已经执行Try。
    2. 悬挂
      执行Try时需要判断当前分支事务是否已经执行Cancel。
    3. 幂等性
      由于Confirm和cancel失败需进行重试,因此需要实现幂等性。

    五 TCC与2PC区别

    TCC本质上也是二阶段提交协议,但他们又有很大不同:

    • TCC作用与服务层,2PC作用于资源层。(TCC开发人员通过业务代码实现数据提交与回滚,2PC基于数据库厂商原生协议,由数据库层面实现数据提交与回滚。)
    • TCC三个接口逻辑由开发人员编写,2PC由数据库厂商或第三方编写。
    • 由于以上两原因,TCC可以自由控制资源锁定的粒度。
    • TCC侵入业务逻辑过强,每个分支事务都需要实现Try、Confirm、Cancel三个接口,改造成本高。

    六 TCC缺点

    • 代码侵入性太强,每个分支事务都得实现Try、Confirm、Cancel。(这一点我可难了,代码量庞大,耦合性高..手动狗头
    • 幂等性难以控制。

    七 TCC的实现框架

    ByteTCC,TCC-transaction,Hmily

  • 相关阅读:
    操作mysql的指令
    linux下安装mongodb
    linux将指令加入开机启动或加入环境变量
    php请求远程url内容方法
    nosql基本了解
    堆排序的实现
    转:导出csv文件数字会自动变科学计数法的解决方法
    jQuery筛选结果等于true的筛选
    转:Jquery的parent和parents(找到某一特定的祖先元素)
    drupal7 带表达式条件的update
  • 原文地址:https://www.cnblogs.com/NEWHOM/p/12406326.html
Copyright © 2011-2022 走看看