`

如何选择分布式事务形态(Fescar、TCC、SAGA、补偿、基于消息的最终一致等等)

 
阅读更多

 

TXC/GTS/Fescar一脉相承:ali TXC(Taobao Transaction Constructor) ->  aliyun GTS(Global TransactionService) ->  Fescar(Fast & EaSy Commit And Rollback, FESCAR)

 

 

各种形态的分布式事务

分布式事务有多种主流形态,包括:

 

基于消息实现的分布式事务

基于补偿实现的分布式事务

基于TCC实现的分布式事务

基于SAGA实现的分布式事务

基于2PC实现的分布式事务

这些形态的原理已经在很多文章中进行了剖析,用“分布式事务”关键字就能搜到对应的文章,本文不再赘述这些形态的原理,并将重点放在如何根据业务选择对应的分布式事务形态上。

 

何时选择单机事务?

这个相信大家都很清楚,在条件允许的情况下,我们应该尽可能地使用单机事务,因为单机事务里,无需额外协调其他数据源,减少了网络交互时间消耗以及协调时所需的存储IO消耗,在修改等量业务数据的情况下,单机事务将会有更高的性能。

 

但单机数据库由于 业务逻辑解耦等因素进行了数据库垂直拆分、或者由于单机数据库性能压力等因素进行了数据库水平拆分之后,数据分布于多个数据库,这时若需要对多个数据库的数据进行协调变更,则需要引入分布式事务。

 

分布式事务的模式有很多种,那究竟要怎么选择适合业务的模式呢?以下我们将从使用场景、性能、开发成本这几个方面进行分析。

 

何时选择基于消息实现的事务?

基于消息实现的事务适用于分布式事务的提交或回滚只取决于事务发起方的业务需求,其他数据源的数据变更跟随发起方进行的业务场景。

 

举个例子,假设存在业务规则:某笔订单成功后,为用户加一定的积分。

 

在这条规则里,管理订单数据源的服务为事务发起方,管理积分数据源的服务为事务跟随者。

 

从这个过程可以看到,基于消息队列实现的事务存在以下操作:

 

订单服务创建订单,提交本地事务

订单服务发布一条消息

积分服务收到消息后加积分

我们可以看到它的整体流程是比较简单的,同时业务开发工作量也不大:

 

编写订单服务里订单创建的逻辑

编写积分服务里增加积分的逻辑

可以看到该事务形态过程简单,性能消耗小,发起方与跟随方之间的流量峰谷可以使用队列填平,同时业务开发工作量也基本与单机事务没有差别,都不需要编写反向的业务逻辑过程。因此基于消息队列实现的事务是我们除了单机事务外最优先考虑使用的形态。

 

何时选择利用补偿实现的事务?

但是基于消息实现的事务并不能解决所有的业务场景,例如以下场景:某笔订单完成时,同时扣掉用户的现金。

 

这里事务发起方是管理订单库的服务,但对整个事务是否提交并不能只由订单服务决定,因为还要确保用户有足够的钱,才能完成这笔交易,而这个信息在管理现金的服务里。这里我们可以引入基于补偿实现的事务,其流程如下:

 

创建订单数据,但暂不提交本地事务

订单服务发送远程调用到现金服务,以扣除对应的金额

上述步骤成功后提交订单库的事务

以上这个是正常成功的流程,异常流程需要回滚的话,将额外发送远程调用到现金服务以加上之前扣掉的金额。

 

以上流程比基于消息队列实现的事务的流程要复杂,同时开发的工作量也更多:

 

编写订单服务里创建订单的逻辑

编写现金服务里扣钱的逻辑

编写现金服务里补偿返还的逻辑

可以看到,该事务流程相对于基于消息实现的分布式事务更为复杂,需要额外开发相关的业务回滚方法,也失去了服务间流量削峰填谷的功能。但其仅仅只比基于消息的事务复杂多一点,若不能使用基于消息队列的最终一致性事务,那么可以优先考虑使用基于补偿的事务形态。

 

(题外话:阿里GTS也是利用补偿实现,只不过补偿代码自动生成,无需业务干预,同时接管应用数据源,禁止业务修改处于全局事务状态中的记录。)

 

何时选择利用TCC实现的事务

然而基于补偿的事务形态也并非能实现所有的需求,如以下场景:某笔订单完成时,同时扣掉用户的现金,但交易未完成,也未被取消时,不能让客户看到钱变少了。

 

这时我们可以引入TCC,其流程如下:

 

订单服务创建订单

订单服务发送远程调用到现金服务,冻结客户的现金

提交订单服务数据

订单服务发送远程调用到现金服务,扣除客户冻结的现金

以上是正常完成的流程,若为异常流程,则需要发送远程调用请求到现金服务,撤销冻结的金额。

 

以上流程比基于补偿实现的事务的流程要复杂,同时开发的工作量也更多:

 

订单服务编写创建订单的逻辑

现金服务编写冻结现金的逻辑

现金服务编写扣除现金的逻辑

现金服务编写解冻现金的逻辑

TCC实际上是最为复杂的一种情况,其能处理所有的业务场景,但无论出于性能上的考虑,还是开发复杂度上的考虑,都应该尽量避免该类事务。

 

何时选择利用SAGA实现的事务?

SAGA可以看做一个异步的、利用队列实现的补偿事务。

 

其适用于无需马上返回业务发起方最终状态的场景,例如:你的请求已提交,请稍后查询或留意通知 之类。

 

将上述补偿事务的场景用SAGA改写,其流程如下:

 

订单服务创建最终状态未知的订单记录,并提交事务

现金服务扣除所需的金额,并提交事务

订单服务更新订单状态为成功,并提交事务

以上为成功的流程,若现金服务扣除金额失败,那么,最后一步订单服务将会更新订单状态为失败。

 

其业务编码工作量比补偿事务多一点,包括以下内容:

 

订单服务创建初始订单的逻辑

订单服务确认订单成功的逻辑

订单服务确认订单失败的逻辑

现金服务扣除现金的逻辑

现金服务补偿返回现金的逻辑

但其相对于补偿事务形态有性能上的优势,所有的本地子事务执行过程中,都无需等待其调用的子事务执行,减少了加锁的时间,这在事务流程较多较长的业务中性能优势更为明显。同时,其利用队列进行进行通讯,具有削峰填谷的作用。

 

因此该形式适用于不需要同步返回发起方执行最终结果、可以进行补偿、对性能要求较高、不介意额外编码的业务场景。

 

但当然SAGA也可以进行稍微改造,变成与TCC类似、可以进行资源预留的形态。

 

2PC事务

其适用于参与者较少,单个本地事务执行时间较少,并且参与者自身可用性很高的场景,否则,其很可能导致性能下降严重。

 

并非一种事务形态就能打遍天下

通过分析我们可以发现,并不存在一种事务形态能解决所有的问题,我们需要根据特定的业务场景选择合适的事务形态。甚至于有时需要混合多种事务形态才能更好的完成目标,如 上面提到的 订单、积分、钱包混合的场景:订单的成功与否需要依赖于钱包的余额,但不依赖于积分的多少,因此可以混合基于消息的事务形态以加积分 及 基于补偿的事务形态以确保扣钱成功,从而得到一个性能更好,编码量更少的形态。

 

然而目前很多框架都专注于某单一方面的事务形态,如TCC单独一个框架,可靠消息单独一个框架,SAGA单独一个框架,他们各自独立,容易导致以下问题:

 

由于前期只采用了其中一种类型事务的框架,因为工具目前只有锤子,引入其他工具又涉及测试、阅读代码等过程,因此把所有问题都看做钉子,导致性能偏低或者实现不够优雅

由于不同框架管理事务的形态可能不一致,导致不能很好的协调工作,如某一个TCC框架和另一个基于消息的事务框架无法很好融合。

解决方案

为了解决上面提到的问题,EasyTransaction这个基于Spring的分布式事务框架,实现了上述除2PC以外的所有事务形态,并提供了统一的使用接口,完美地解决了以上的问题。其主要特性如下:

 

一个框架包含多种事务形态,一个框架搞定所有类型的事务

多种事务形态可混合使用

高性能,若不启用框架的幂等功能,对业务数据库的额外消耗仅为写入25字节的一行

可选的框架幂等实现(包括调用次序错乱处理),大幅减轻业务开发工作量

业务代码可实现完全无入侵

支持嵌套事务

无需额外部署协调者,不同APP的服务协调自身发起的事务

分布式事务ID可关联业务ID,业务类型,APPID,便于监控各个业务的分布式事务执行情况

若各位对ET兴趣,可以到 https://github.com/QNJR-GROUP/EasyTransaction 查看详细介绍及示例,本文不再深入介绍

 

总结

不同业务场景应按需引入不同的事务形态,在条件允许的情况下,个人建议按照如下次序选择对应的事务形态:

 

单机事务》基于消息的事务》基于补偿的事务》TCC事务

1

因SAGA事务的形态需要配合较为明显的前端业务交互变更,个人建议在单一事务执行过程较长、存在较多子事务,并且无法使用基于消息的事务形态时使用。

<audio controls="controls" style="display: none;"></audio>

<audio controls="controls" style="display: none;"></audio>

分享到:
评论

相关推荐

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

    在分布式事务中,XA、Saga、TCC和MQ补偿等解决方案都可以用于实现分布式事务的一致性和可靠性。每种解决方案都有其特点和优势,选择哪种解决方案取决于具体的业务需求和系统架构。 在 MySQL 中,XA 事务可以通过...

    基于Hyperf框架的TCC分布式事务组件.zip

    而TCC分布式事务组件则是Hyperf对分布式事务处理的一个重要补充,使得开发者能够在微服务环境中处理复杂的业务逻辑,保证数据的一致性。 TCC模式的核心思想是将一个全局事务拆分为多个本地事务,每个本地事务对应一...

    分布式事务框架Fescar在SpringCloud环境下的应用实践-fescar-demo.zip

    同时,根据服务规模和业务需求,合理选择事务模式(如TCC、Saga、补偿型事务等)也至关重要。 总之,Fescar提供了一种高效且易于集成的分布式事务解决方案,通过与SpringCloud的结合,可以有效地帮助我们在微服务...

    Hulk-高性能分布式事务框架(TCC模式基于SpringCloud)

    《Hulk:高性能分布式事务框架基于SpringCloud的TCC模式详解》 在现代企业级应用中,事务处理是核心功能之一,确保数据的一致性和完整性至关重要。Hulk是一款优秀的高性能分布式事务框架,它以TCC(Try-Confirm-...

    基于本地消息表的分布式事务处理-tcc.zip

    在本压缩包"基于本地消息表的分布式事务处理-tcc.zip"中,包含的项目"tcc-master"可能是一个关于如何结合这两种方法实现高效、可靠的分布式事务解决方案的示例。 本地消息表是一种在分布式环境中保证事务一致性的...

    基于Hyperf的TCC分布式事务-tcc-transaction.zip

    总之,"基于Hyperf的TCC分布式事务-tcc-transaction.zip"项目为开发者提供了一个实践TCC模式的起点,通过这个项目,你可以深入了解如何在Hyperf中实现高效的分布式事务处理,提升微服务架构中的数据一致性。...

    分布式事务解决方案FESCAR.docx

    - **侵入业务的方案**:这类方案要求在业务逻辑层面考虑分布式事务,比如使用可靠消息的最终一致性方案或TCC/Saga模式。虽然这些方法可以解决问题,但增加了开发和维护成本。 #### 三、理想方案的特点 理想的...

    java分布式事务demo

    6. **分布式事务的NoSQL解决方案**:如CAP理论中的CP(Consistency与Partition Tolerance)取舍,很多NoSQL数据库如MongoDB、Cassandra提供了最终一致性,它们在分布式事务上有不同的处理方式。 7. **分布式事务的...

    TCC-Transaction分布式事务DEMO

    在这个名为"TCC-Transaction分布式事务DEMO"的项目中,我们将深入探讨TCC模式以及如何在基于Mysql数据库的环境中实现它。 **TCC模式详解** TCC(Try-Confirm-Cancel)是一种补偿型的分布式事务处理模式,主要由三...

    TCC实现分布式事物,java 源码

    TCC(Try-Confirm-Cancel)模式是一种实现分布式事务的策略,它允许在不同的应用程序和服务之间保持数据的一致性。本文将深入探讨TCC的基本原理、如何在Java中实现以及涉及到的关键技术。 TCC模式的核心思想是将一...

    分布式事务专题-v1.1.pdf

    除了传统的分布式事务解决方案外,还有一些基于特定数据库的中间件产品,比如阿里巴巴的Seata,它为分布式事务提供了易用的解决方案,并支持 AT (自动补偿事务)、TCC (Try-Confirm/Cancel)、SAGA 和 XA 模式。...

    (源码)基于TCC分布式事务框架的分布式事务管理系统.zip

    # 基于TCC分布式事务框架的分布式事务管理系统 ## 项目简介 本项目是一个基于TCC(TryConfirmCancel)分布式事务框架的分布式事务管理系统。TCC是一种分布式事务处理模式,通过将事务分为Try、Confirm和Cancel三个...

    rest-tcc分布式事务

    本章旨在探讨一种基于Try-Cancel/Confirm (TCC)模式的轻量级RESTful分布式事务解决方案。 #### 二、TCC模式详解 ##### 2.1 TCC模式简介 TCC模式是一种通过Try、Confirm、Cancel三个阶段来确保分布式事务的一致性...

    微服务架构的分布式事务控制及解决方案视频教程

    最全分布式事务视频课程详细讲解,需要的小伙伴自行百度网盘下载,链接见附件,永久有效。...5.分布式事务解决方案之可靠消息最终一致性 6.分布式事务解决方案之最大努力通知 7.分布式事务综合案例分析

    分布式事务 Seata TCC 模式深度解析

    本文档的内容主要分为以下四个部分: ...2、从 TCC 的业务模型与并发控制分享如何设计一个 TCC 接口,并且适配 TCC 模型; 3、如何控制异常; 4、性能优化,使得 TCC 模式能够满足更高的业务需求。

    分布式事务分类,xa,at,tcc,sega

    ### 分布式事务基础知识 #### 一、ACID特性与CAP理论 在深入探讨不同分布式事务解决方案之前,我们首先需要理解分布式系统中的两个核心概念——ACID特性和CAP理论。 **ACID特性**: 1. **原子性(Atomicity)**...

    分布式事务若依框架文档

    - **Saga模式**:Saga模式是一种长活事务模式,通过一系列本地事务(每个服务内)的顺序执行来完成整个分布式事务,通过补偿机制保证事务的最终一致性。 #### 五、Seata的安装与使用 - **下载安装**:可以在GitHub...

    分布式事务实践 解决数据一致性

    详细介绍3种分布式事务实现的模式中的消息驱动模式并通过完整实例演示了消息驱动模式下,实现微服务系统的分布式事务的完整过程。 7-1 分布式事务实现:消息驱动模式 7-2 消息驱动模式实例:设计 7-3 消息驱动模式...

    分布式事务-可靠消息的服务的设计与实现(消息服务子系统)

    3. **消息队列(MQ)**:在分布式事务中,可靠消息服务通常是基于消息队列实现的,如RabbitMQ、Kafka或RocketMQ等。消息队列作为异步中间件,可以确保消息的可靠传递,实现最终一致性。 4. **两阶段提交(2PC)**:...

Global site tag (gtag.js) - Google Analytics