分布式事务(第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

原文地址:https://www.cnblogs.com/NEWHOM/p/12406326.html

时间: 2024-11-01 20:57:54

分布式事务(第05篇)分布式事务解决方法-TCC的相关文章

事务 锁 高并发下的解决方法

最近要做一个高并发的游戏后台网站,要在已有的后台对其系统进行优化,让我对高并发系统又有了一次比较深刻的认识. 对于高并发系统解决方法 1 事务 事务级别的高低,决定了对于并发处理的效率.事务级别越高,处理并发的能力就越低,不过数据一致性也会越高. 事务有5个级别: (一)未提交读 未提交读是最低的事务隔离级别,允许读取其他事务已经修改但未提交的数据行.SQL SERVER 当此事务等级进行尝试读取数据时,不会放置共享锁,直接读取数据,所以忽略已存在的互斥锁.换句话说,即使该资源已经受到了独占锁的

SpringMVC + Spring + MyBatis 学习笔记:SpringMVC和Spring一同工作的时候,AOP事务管理不起作用的解决方法

系统:WIN8.1 数据库:Oracle 11GR2 开发工具:MyEclipse 8.6 框架:Spring3.2.9.SpringMVC3.2.9.MyBatis3.2.8 SpringMVC 的 springmvc.xml文件中 配置扫描包,不要包含 service的注解,Spring 的 配置文件配置包扫描时,不要包含controller的注解,如下所示: Spring MVC的配置文件: <context:component-scan base-package="包路径"

Spring @Cacheable注解 &amp;&amp; 事务@Transactional 在同一个类中的方法调用不生效

@Cacheable 注解在对象内部调用不会生效 代码示例:ProductServiceImpl.java public List<ProductInfoVO> getProductList(CommonRequest<ProductInfoDTO> reqest) { // @Cacheable失效,不会走缓存的 return this.findProductInfoList(reqest); } @Cacheable(cacheNames = "productInfo

web 开发之js---页面缓存, jsp 缓存, html 缓存, ajax缓存,解决方法

有关页面缓存问题.这个问题上网找了好多.但发觉各种解决方法,都彼此分离,没有一篇统一的解决方法,本人近日,也遇到了页面缓存的问题,根据网上各页面缓存的解答,做了一个总结. 1.服务器端缓存的问题, 防止JSP页面缓存: [java] view plaincopy <% // 将过期日期设置为一个过去时间 response.setHeader("Expires", "Sat, 6 May 1995 12:00:00 GMT"); // 设置 HTTP/1.1 n

搞懂分布式技术19:使用RocketMQ事务消息解决分布式事务

搞懂分布式技术19:使用RocketMQ事务消息解决分布式事务 初步认识RocketMQ的核心模块 rocketmq模块 rocketmq-broker:接受生产者发来的消息并存储(通过调用rocketmq-store),消费者从这里取得消息. rocketmq-client:提供发送.接受消息的客户端API. rocketmq-namesrv:NameServer,类似于Zookeeper,这里保存着消息的TopicName,队列等运行时的元信息.(有点NameNode的味道) rocketm

还不理解“分布式事务”?这篇给你讲清楚!

这篇文章将介绍什么是分布式事务,分布式事务解决什么问题,对分布式事务实现的难点,解决思路,不同场景下方案的选择,通过图解的方式进行梳理.总结和比较. 相信耐心看完这篇文章,谈到分布式事务,不再只是有“2PC”.“3PC”.“MQ的消息事务”.“最终一致性”.“TCC”等这些知识碎片,而是能够将知识连成一片,形成知识体系. 什么是事务 介绍分布式事务之前,先介绍什么是事务. 事务的具体定义 事务提供一种机制将一个活动涉及的所有操作纳入到一个不可分割的执行单元,组成事务的所有操作只有在所有操作均能正

分布式事务及其解决方法

分布式事务是企业集成中的一个技术难点,也是每一个分布式系统架构中都会涉及到的一个东西,特别是在微服务架构中,几乎可以说是无法避免,本文就分布式事务来简单聊一下. 数据库事务 在说分布式事务之前,我们先从数据库事务说起. 数据库事务可能大家都很熟悉,在开发过程中也会经常使用到.但是即使如此,可能对于一些细节问题,很多人仍然不清楚.比如很多人都知道数据库事务的几个特性:原子性(Atomicity ).一致性( Consistency ).隔离性或独立性( Isolation)和持久性(Durabil

分布式事务如何拆解成单机事务

这段时间一直在思考分布式事务的实现,一开始的思路总是停留在应用层面上,后来经过查看相关资料才知道,要支持分布式事务得需要数据库的支持,也就还是回到了数据库层面,另外在Java里面结合javax.sql扩展包,使用两段提交协议能轻松支持分布式事务. 后来自己结合之前做过的一些项目,发现原来之前实现的功能已经利用消息队列把分布式事务拆解成单机事务了,虽然实时性可能没有那么强,但是正常情况下,这种思路还是比较好的一种解决方案.只是以前不知道这个概念,但是却是实现了这个功能. 关于分布式事务的拆解的分析

深入理解分布式事务,高并发下分布式事务的解决方案

这两天正在研究微服务架构中分布式事务的处理方案, 做一个小小的总结, 作为备忘. 如有错误, 欢迎指正! 概念澄清 事务补偿机制: 在事务链中的任何一个正向事务操作, 都必须存在一个完全符合回滚规则的可逆事务. CAP理论: CAP(Consistency, Availability, Partition Tolerance), 阐述了一个分布式系统的三个主要方面, 只能同时择其二进行实现. 常见的有CP系统, AP系统. 幂等性: 简单的说, 业务操作支持重试, 不会产生不利影响. 常见的实现