`
zhaoshijie
  • 浏览: 2265506 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

事务补偿机制

 
阅读更多
关键字:事务补偿机制
淘宝梁飞分析分布式 文章:http://javatar.iteye.com/blog/981787


可以设想一个最简单的分布式事务场景,对于跨银行的转账操作,该操作涉及到调用两个异地的Service服务,一个是本地提供的取款服务,一个是目标银行提供的存款服务,该两个服务本身无状态且独立,构成一个完整的事务。对于事务的处理初步分析:

事务补偿机制

事务补偿即在事务链中的任何一个正向事务操作,都必须存在一个完全符合回滚规则的可逆事务。如果是一个完整的事务链,则必须事务链中的每一个业务服务或操作都有对应的可逆服务。对于Service服务本身无状态,也不容易实现前面讨论过的通过DTC或XA机制实现的跨应用和资源的事务管理,建立跨资源的事务上下文。因此也较难以实现真正的预提交和正式提交的分离。

在这种情况下以上面例子来说,首先调用取款服务,完全调用成功并返回,数据已经持久化。然后调用异地的存款服务,如果也调用成功,则本身无任何问题。如果调用失败,则需要调用本地注册的逆向服务(本地存款服务),如果本地存款服务调用失败,则必须考虑重试,如果约定重试次数仍然不成功,则必须log到完整的不一致信息。也可以是将本地存款服务作为消息发送到消息中间件,由消息中间件接管后续操作。

在上面方式中可以看到需要手工编写大量的代码来处理以保证事务的完整性,我们可以考虑实现一个通用的事务管理器,实现事务链和事务上下文的管理。对于事务链上的任何一个服务正向和逆向操作均在事务管理和协同器上注册,由事务管理器接管所有的事务补偿和回滚操作。

基于消息的最终一致性

在这里首先要回答的是我们需要时实时一致性还是最终一致性的问题,如果需要的是最终一致性,那么BASE策略中的基于消息的最终一致性是比较好的解决方案。这种方案真正实现了两个服务的真正解耦,解耦的关键就是异步消息和消息持久化机制。

还是以上面的例子来看。对于转账操作,原有的两个服务调用变化为第一步调用本地的取款服务,第二步发送异地取款的异步消息到消息中间件。如果第二步在本地,则保证事务的完整性基本无任何问题,即本身就是本地事务的管理机制。只要两个操作都成功即可以返回客户成功。

由于解耦,我们看到客户得到成功返回的时候,如果是上面一种情况则异地卡马上就能查询账户存款增加。而第二种情况则不一定,因为本身是一种异步处理机制。消息中间件得到消息后会去对消息解析,然后调用异地银行提供的存款服务进行存款,如果服务调用失败则进行重试。

异地银行存款操作不应该长久地出现异常而无法使用,因此一旦发现异常我们可以迅速的解决,消息中间件中异常服务自然会进行重试以保证事务的最终一致性。这种方式假设问题一定可以解决,在不到万不得已的情况下本地的取款服务一般不进行可逆操作。

在本地取款到异地存款两个服务调用之间,会存在一个真空期,这段时间相关现金不在任何一个账户,而只是在一个事务的中间状态,但是客户并不关心这个,只要在约定的时间保证事务最终的一致性即可。

关于等幂操作的问题

重复调用多次产生的业务结果与调用一次产生的业务结果相同,简单点讲所有提供的业务服务,不管是正向还是逆向的业务服务,都必须要支持重试。因为服务调用失败这种异常必须考虑到,不能因为服务的多次调用而导致业务数据的累计增加或减少。

关于是否可以补偿的问题

在这里我们谈的是多个跨系统的业务服务组合成一个分布式事务,因此在对事务进行补偿的时候必须要考虑客户需要的是否一定是最终一致性。客户对中间阶段出现的不一致的承受度是如何的。

在上面的例子来看,如果采用事务补偿机制,基本可以是做到准实时的补偿,不会有太大的影响。而如果采用基于消息的最终一致性方式,则可能整个周期比较长,需要较长的时间才能给得到最终的一致性。比如周六转款,客户可能下周一才得到通知转账不成功而进行了回退,那么就必须要考虑客户是否能给忍受。

其次对于前面讨论,如果真正需要的是实时的一致性,那么即使采用事务补偿机制,也无法达到实时的一致性。即很可能在两个业务服务调用中间,客户前台业务操作对持久化的数据进行了其它额外的操作。在这种模式下,我们不得不考虑需要在数据库表增加业务状态锁的问题,即整个事务没有完整提交并成功前,第一个业务服务调用虽然持久化在数据库,但是仍然是一个中间状态,需要通过业务锁来标记,控制相关的业务操作和行为。但是在这种模式下无疑增加了整个分布式业务系统的复杂度。
分享到:
评论
1 楼 skyesx 2017-04-07  
博主文中提到的 事务补偿 及 相关的事务管理器目前在github中已有开源实现,能自动处理补偿,幂等 等问题,参考 https://github.com/QNJR-GROUP/EasyTransaction

相关推荐

    命令模式实现事务补偿2

    **事务补偿机制** 在分布式环境中尤为重要,因为单个服务的失败可能会影响到整个业务流程。例如,一个订单的创建可能涉及到库存扣减、支付处理等多个步骤,如果其中一个步骤失败,就需要回滚之前成功完成的步骤,以...

    命令模式实现事务补偿

    然而,在分布式环境中,由于网络延迟、服务故障等原因,简单的本地事务无法满足需求,因此出现了事务补偿机制。本文将深入探讨如何通过命令模式实现一种事务补偿策略。 命令模式是一种行为设计模式,它将请求封装为...

    dubbo-tcc:关于dubbo事务补偿机制的

    《Dubbo TCC事务补偿机制详解》 在分布式系统中,事务处理的复杂性远超单体应用。Dubbo作为一款高性能、轻量级的Java服务框架,为了解决分布式环境下的事务一致性问题,引入了TCC(Try-Confirm-Cancel)事务补偿...

    分布式事务常用的解决方案,XA,Saga,TCC,MQ补偿.docx

    分布式事务的解决方案有很多,常见的有XA、Saga、TCC和MQ补偿等。 XA(eXtended Architecture)是开放集团(Open Group)提出的分布式事务处理规范,被广泛应用于数据库厂商。XA规范定义了分布式事务处理的模型和...

    Mycat事务补偿设计文档

    ### Mycat事务补偿设计文档解析 #### 概述 在数据分片的场景下,单一数据库的事务处理机制已无法满足复杂系统的需求。因此,针对此类情况,分布式事务处理成为了一个必要的解决方案。本文档旨在介绍Mycat在分布式...

    补偿型事务处理机制时序图

    分布式业务补偿型事务处理机制是现代企业级应用中确保数据一致性的重要手段,特别是在微服务架构中,由于服务间的异步操作和复杂交互,事务管理变得尤为关键。标题中的“补偿型事务处理机制时序图”指的是通过补偿...

    (源码)基于SpringCloud和Hmily的分布式事务管理系统.zip

    事务补偿提供事务补偿机制,确保在事务失败时能够进行回滚操作。 ### 2. Spring Cloud集成 服务注册与发现集成Eureka作为服务注册中心,实现服务的自动注册与发现。 负载均衡使用Ribbon进行客户端负载均衡,确保...

    基于事务的分布式虚拟化环境下服务替换方法.pdf

    即在服务替换时,确保每一个服务都具备事务属性,并能够通过事务补偿机制来保证在服务发生故障时,系统能够回滚到一致性状态,或者采取补偿措施以恢复服务组合的正确运行。 5. 分层的服务组合模型:文章提出了一种...

    电商系统的分布式事务调优

    分布式事务在电商系统中的重要性不言而喻,特别是在微服务架构盛行的今天。...同时,为了提高系统的健壮性和可用性,还需要结合其他技术如幂等性设计、事务补偿机制、分布式锁等来进一步优化分布式事务的处理。

    CRM基于分布式数据存储事务处理方案.pdf

    在“二、关键业务场景实现方案”中,作者提出了分布式系统的三种事务处理方式,分别是分布式事务两阶段提交、基于BestEfforts1PC模式的事务以及事务补偿机制,并指出事务补偿机制在实践中更为常见。关于事务一致性的...

    微服务架构-分布式事务设计方案分享.pdf

    **事务补偿机制**:在分布式事务中,如果一个操作是正向的,那么应该存在一个与其匹配的反向操作,以便在出错时进行回滚。这种机制确保了事务的可逆性,从而保持数据的一致性。 **CAP理论**:一致性(Consistency)...

    CAP-develop (1).zip

    7. **事务补偿机制**:在分布式事务中,除了正常流程外,还需要有异常处理和补偿机制,以应对可能出现的失败情况。项目可能包含了补偿事务(如Saga模式)或重试策略等。 8. **代码组织与设计模式**:CAP-develop...

    基于异步通信的微服务分布式事务管理机制研究分析.pdf

    在深入分析微服务分布式事务管理机制的基础上,我们将探讨如何在异步通信模式下实现微服务架构中的事务一致性,并深入理解与之相关的概念与技术。 首先,微服务架构是目前软件工程中一种流行的服务组织方式,其主要...

    事务机制及相关代码实现

    在IT领域,事务是数据库操作的核心概念,它确保了数据的一致性和完整性。事务机制是数据库管理系统中的一个...同时,随着分布式系统的普及,分布式事务如2PC(两阶段提交)、TCC(尝试、确认、补偿)等也成为研究热点。

Global site tag (gtag.js) - Google Analytics