分布式事务-XA-DTP-TCC-BASE介绍
前言
数据库事务(简称:事务,Transaction)是指数据库执行过程中的一个逻辑单位,由一个有限的数据库操作序列构成。
事务拥有以下四个特性,习惯上被称为 ACID 特性:
-
原子性(Atomicity):事务作为一个整体被执行,包含在其中的对数据库的操作要么全部被执行,要么都不执行。
-
一致性(Consistency):事务应确保数据库的状态从一个一致状态转变为另一个一致状态。一致状态是指数据库中的数据应满足完整性约束。除此之外,一致性还有另外一层语义,就是事务的中间状态不能被观察到(这层语义也有说应该属于原子性)。
-
隔离性(Isolation):多个事务并发执行时,一个事务的执行不应影响其他事务的执行,如同只有这一个操作在被数据库所执行一样。
-
持久性(Durability):已被提交的事务对数据库的修改应该永久保存在数据库中。在事务结束时,此操作将不可逆转。
二、本地事务
在单个数据库的本地并且限制在单个进程内的事务
本地事务不涉及多个数据来源
三、全局事务(DTP模型)--标准分布式事务
AP(Application Program):也就是应用程序,可以理解为使用 DTP 的程序
RM(Resource Manager):资源管理器(这里可以是一个 DBMS,或者消息服务器管理系统)应用程序通过资源管理器对资源进行控制,资源必须实现 XA 定义的接口
TM(Transaction Manager):事务管理器,负责协调和管理事务,提供给 AP 应用程序编程接口以及管理资源管理器
事务管理器控制着全局事务,管理事务生命周期,并协调资源。资源管理器负责控制和管理实际资源
1、什么是分布式事务
分布式事务就是指事务的参与者、支持事务的服务器、资源服务器以及事务管理器分别位于不同的分布式系统的不同节点之上。以上是百度百科的解释,简单的说,就是一次大的操作由不同的小操作组成,这些小的操作分布在不同的服务器上,且属于不同的应用,分布式事务需要保证这些小操作要么全部成功,要么全部失败。本质上来说,分布式事务就是为了保证不同数据库的数据一致性。
分布式事务三大难题:一致性、高性能和易用性
分布式系统的事务一致性本身是一个技术难题,没有一种简单完美的方案能够应对所有场景,很难兼顾事务一致性,高性能与易用性。三者缺一,则适用场景大大受限,实用价值不高。
首先是一致性:要求在各种异常情况下保证数据是强一致的。目前最常见的一致性解决方案是最终一致性方案,通常是结合消息中间件实现,在互联网企业中广泛使用。最终一致性实现方案比较复杂,开发、运维成本高,并且与强一致相比,业务上是受很多限制的。
其次是高性能:目前基于XA协议的两阶段提交是最常见的分布式事务解决方案,但XA类产品的典型不足是性能低下,这对于互联网大并发需求下的多数企业是无法接受的。国外具有几十年历史和技术沉淀的基于XA模型的商用分布式事务产品,在相同软硬件条件下,开启分布式事务后吞吐经常有数量级的下降。
第三是易用性:为了满足一致性和高性能要求,出现了一些特定场景下的分布式事务方案,但通常会限制用户用法,对业务侵入性强,无法做到简单易用,带来更多开发成本。
2、分布式事务的产生的原因
2.1、数据库分库分表
当数据库单表一年产生的数据超过1000W,那么就要考虑分库分表,具体分库分表的原理在此不做解释,以后有空详细说,简单的说就是原来的一个数据库变成了多个数据库。这时候,如果一个操作既访问01库,又访问02库,而且要保证数据的一致性,那么就要用到分布式事务。
2.2、应用SOA化
所谓的SOA化,就是业务的服务化。比如原来单机支撑了整个电商网站,现在对整个网站进行拆解,分离出了订单中心、用户中心、库存中心。对于订单中心,有专门的数据库存储订单信息,用户中心也有专门的数据库存储用户信息,库存中心也会有专门的数据库存储库存信息。这时候如果要同时对订单和库存进行操作,那么就会涉及到订单数据库和库存数据库,为了保证数据一致性,就需要用到分布式事务。
一、什么是XA规范
XA 是由 X/Open 组织提出的分布式事务规范,XA 规范主要定义了事务协调者(Transaction Manager)和资源管理器(Resource Manager)之间的接口。
在XA规范之前,存在着一个DTP模型,该模型规范了分布式事务的模型设计。
DTP规范中主要包含了AP、RM、TM三个部分,其中AP是应用程序,是事务发起和结束的地方;RM是资源管理器,主要负责管理每个数据库的连接数据源;TM是事务管理器,负责事务的全局管理,包括事务的生命周期管理和资源的分配协调等。
二、XA是如何工作的
XA事务是两阶段提交的一种实现方式,根据 2PC 的规范,XA 将一次事务分割成了两个阶段,即 Prepare 和 Commit 阶段。
Prepare 阶段, TM 向所有 RM 发送 prepare 指令,RM 接受到指令后,执行数据修改和日志记录等操作,然后返回可以提交或者不提交的消息给 TM。如果事务协调者 TM 收到所有参与者都准备好的消息,会通知所有的事务提交,然后进入第二阶段。
Commit 阶段, TM 接受到所有 RM 的 prepare 结果,如果有 RM 返回是不可提交或者超时,那么向所有 RM 发送 Rollback 命令;如果所有 RM 都返回可以提交,那么向所有 RM 发送 Commit 命令,完成一次事务操作。
DTP 模型中包含一个全局事务管理器(TM,Transaction Manager)和多个资源管理器(RM,Resource Manager)。全局事务管理器负责管理全局事务状态与参与的资源,协同资源一起提交或回滚;资源管理器则负责具体的资源操作。
XA 协议描述了 TM 与 RM 之间的接口,允许多个资源在同一分布式事务中访问。
基于 DTP 模型的分布式事务流程大致如下:
1、应用程序(AP,Application)向 TM 申请开始一个全局事务。
2、针对要操作的 RM,AP 会先向 TM 注册(TM 负责记录 AP 操作过哪些 RM,即分支事务),TM 通过 XA 接口函数通知相应 RM 开启分布式事务的子事务,接着 AP 就可以对该 RM 管理的资源进行操作。
3、当 AP 对所有 RM 操作完毕后,AP 根据执行情况通知 TM 提交或回滚该全局事务,TM 通过 XA 接口函数通知各 RM 完成操作。TM 会先要求各个 RM 做预提交,所有 RM 返回成功后,再要求各 RM 做正式提交,XA 协议要求,一旦 RM 预提交成功,则后续的正式提交也必须能成功;如果任意一个 RM 预提交失败,则 TM 通知各 RM 回滚。
4、所有 RM 提交或回滚完成后,全局事务结束。
原子性
XA 协议使用 2PC(Two Phase Commit,两阶段提交)原子提交协议来保证分布式事务原子性。
两阶段提交是指将提交过程分为两个阶段,即准备阶段(投票阶段)和提交阶段(执行阶段):
隔离性
XA 协议中没有描述如何实现分布式事务的隔离性,但是 XA 协议要求DTP 模型中的每个 RM 都要实现本地事务,也就是说,基于 XA 协议实现的分布式事务的隔离性是由每个 RM 本地事务的隔离性来保证的,当一个分布式事务的所有子事务都是隔离的,那么这个分布式事务天然的就实现了隔离性。
以 MySQL 来举例,MySQL 使用 2PL(Two-Phase Locking,两阶段锁)机制来控制本地事务的并发,保证隔离性。2PL 与 2PC 类似,也是将锁操作分为加锁和解锁两个阶段,并且保证两个阶段完全不相交。加锁阶段,只加锁,不放锁。解锁阶段,只放锁,不加锁。
一致性
前面提到一致性有两层语义,一层是确保事务执行结束后,数据库从一个一致状态转变为另一个一致状态。另一层语义是事务执行过程中的中间状态不能被观察到。
前一层语义的实现很简单,通过原子性、隔离性以及 RM 自身一致性的实现就可以保证。至于后一层语义,我们先来看看单个 RM 上的本地事务是怎么实现的。还是以 MySQL 举例,MySQL 通过 MVCC(Multi Version Concurrency Control,多版本并发控制)机制,为每个一致性状态生成快照(Snapshot),每个事务看到的都是各Snapshot对应的一致性状态,从而也就保证了本地事务的中间状态不会被观察到。
小结
XA 协议通常实现在数据库资源层,直接作用于资源管理器上。因此,基于 XA 协议实现的分布式事务产品,无论是分布式数据库,还是分布式事务框架,对业务几乎都没有侵入,就像使用普通数据库一样。
XA 协议严格保障事务 ACID 特性,能够满足所有业务领域的功能需求,但是,这同样是一把双刃剑。
由于隔离性的互斥要求,在事务执行过程中,所有的资源都被锁定,只适用于执行时间确定的短事务。同时,整个事务期间都是独占数据,对于热点数据的并发性能可能会很低,实现了分布式 MVCC 或乐观锁(optimistic locking)以后,性能可能会有所提升。
同时,为了保障一致性,要求所有 RM 同等可信、可靠,要求故障恢复机制可靠、快速,在网络故障隔离的情况下,服务基本不可用。
三、 什么是TCC 事务模型
TCC(Try-Confirm-Cancel)分布式事务模型相对于 XA 等传统模型,其特征在于它不依赖资源管理器(RM)对分布式事务的支持,而是通过对业务逻辑的分解来实现分布式事务。
TCC 模型认为对于业务系统中一个特定的业务逻辑,其对外提供服务时,必须接受一些不确定性,即对业务逻辑初步操作的调用仅是一个临时性操作,调用它的主业务服务保留了后续的取消权。如果主业务服务认为全局事务应该回滚,它会要求取消之前的临时性操作,这就对应从业务服务的取消操作。而当主业务服务认为全局事务应该提交时,它会放弃之前临时性操作的取消权,这对应从业务服务的确认操作。每一个初步操作,最终都会被确认或取消。
TCC 提出了一种新的事务模型,基于业务层面的事务定义,锁粒度完全由业务自己控制,目的是解决复杂业务中,跨表跨库等大颗粒度资源锁定的问题。TCC 把事务运行过程分成 Try、Confirm / Cancel 两个阶段,每个阶段的逻辑由业务代码控制,避免了长事务,可以获取更高的性能。
四、TCC是如何工作的
TCC 分布式事务模型包括三部分:
-
主业务服务:主业务服务为整个业务活动的发起方,服务的编排者,负责发起并完成整个业务活动。
-
从业务服务:从业务服务是整个业务活动的参与方,负责提供 TCC 业务操作,实现初步操作(Try)、确认操作(Confirm)、取消操作(Cancel)三个接口,供主业务服务调用。
-
业务活动管理器:业务活动管理器管理控制整个业务活动,包括记录维护 TCC 全局事务的事务状态和每个从业务服务的子事务状态,并在业务活动提交时调用所有从业务服务的 Confirm 操作,在业务活动取消时调用所有从业务服务的 Cancel 操作。
Try 阶段: 调用 Try 接口,尝试执行业务,完成所有业务检查,预留业务资源。
Confirm 或 Cancel 阶段: 两者是互斥的,只能进入其中一个,并且都满足幂等性,允许失败重试。
Confirm 操作: 对业务系统做确认提交,确认执行业务操作,不做其他业务检查,只使用 Try 阶段预留的业务资源。
Cancel 操作: 在业务执行错误,需要回滚的状态下执行业务取消,释放预留资源。
Try 阶段失败可以 Cancel,如果 Confirm 和 Cancel 阶段失败了怎么办?
TCC 中会添加事务日志,如果 Confirm 或者 Cancel 阶段出错,则会进行重试,所以这两个阶段需要支持幂等;如果重试失败,则需要人工介入进行恢复和处理等。
原子性
TCC 模型也使用 2PC 原子提交协议来保证事务原子性。Try 操作对应2PC 的一阶段准备(Prepare);Confirm 对应 2PC 的二阶段提交(Commit),Cancel 对应 2PC 的二阶段回滚(Rollback),可以说 TCC 就是应用层的 2PC。
隔离性
TCC 分布式事务模型仅提供两阶段原子提交协议,保证分布式事务原子性。事务的隔离交给业务逻辑来实现。
隔离的本质是控制并发,防止并发事务操作相同资源而引起的结果错乱。
一致性
再来看看 TCC 分布式事务模型下的一致性实现。与 XA 协议实现一致性第一层语义类似,通过原子性保证事务的原子提交、业务隔离性控制事务的并发访问,实现分布式事务的一致性状态转变。
至于第二层语义:事务的中间状态不能被观察到。我们来看看,在 SOA分布式应用环境下是否是必须的。
小结
TCC 分布式事务模型的业务实现特性决定了其可以跨 DB、跨服务实现资源管理,将对不同的 DB 访问、不同的业务操作通过 TCC 模型协调为一个原子操作,解决了分布式应用架构场景下的事务问题。
TCC 模型通过 2PC 原子提交协议保证分布式事务的的原子性,把资源层的隔离性上升到业务层,交给业务逻辑来实现。TCC 的每个操作对于资源层来说,就是单个本地事务的使用,操作结束则本地事务结束,规避了资源层在 2PC 和 2PL 下对资源占用导致的性能低下问题。
同时,TCC 模型也可以根据业务需要,做一些定制化的功能,比如交易异步化实现削峰填谷等。
但是,业务接入 TCC 模型需要拆分业务逻辑成两个阶段,并实现 Try、Confirm、Cancel 三个接口,定制化程度高,开发成本高。
四、 TCC与XA对比
-
XA是资源层面的分布式事务,强一致性,在两阶段提交的整个过程中,一直会持有资源的锁。基于数据库锁实现,需要数据库支持XA协议,由于在执行事务的全程都需要对相关数据加锁,一般高并发性能会比较差
-
TCC是业务层面的分布式事务,最终一致性,不会一直持有资源的锁,性能较好。但是对微服务的侵入性强,微服务的每个事务都必须实现try、confirm、cancel等3个方法,开发成本高,今后维护改造的成本也高为了达到事务的一致性要求,try、confirm、cancel接口必须实现幂等性操作由于事务管理器要记录事务日志,必定会损耗一定的性能,并使得整个TCC事务时间拉长
两者的区别
XA是把所有数据执行成功的通知发送给协调器(第一阶段),协调器在执行commit(第二阶段)
TCC是第一阶段就把事务commit了(try接口),TCC的第二阶段是一个确认(Confirm)的阶段,也就是说只需要调用各个子系统里的confirm逻辑,所以在执行confirm逻辑的时候,并不会持有数据库的锁,所以不会产生性能问题。
TCC与DTP区别
TCC模型的发起方类似于DTP模型的AP,TCC模型的接收方类似于DTP模型的RM
TCC模型中发起方(比如订单服务)调用接收方(比如库存服务,账户服务,积分服务),而DTP模型是由AP应用操作多个RM数据库
两者都实现了2PC
TCC模型:第一阶段由发起方(订单服务)发出try请求,第二阶段由事务管理器发起confirm/cancel请求,而且采用了异步实现
DTP模型:RM(数据库)提供了prepare/commit/rollback接口,两阶段都是由TM调用
TCC的优缺点
优点
解决了跨服务的业务操作原子性问题,例如组合支付、下订单减库存等场景非常实用
TCC的本质原理是把数据库的二阶段提交上升到微服务来实现,从而避免数据库二阶段中锁冲突的长事务引起的低性能风险
TCC异步高性能,它采用了try先检查,然后异步实现confirm,真正提交是在confirm方法中
缺点
对微服务的侵入性强,微服务的每个事务都必须实现try、confirm、cancel等3个方法,开发成本高,今后维护改造的成本也高
为了达到事务的一致性要求,try、confirm、cancel接口必须实现幂等性操作
由于事务管理器要记录事务日志,必定会损耗一定的性能,并使得整个TCC事务时间拉长,建议采用Redis的方式来记录事务日志
————————————————
XA-TCC的介绍
XA 协议在架构上与 TCC 模型相比,最大的不同是 XA 直接作用于资源层,而后者作用于服务层。
资源层更普适,并且对业务几乎没有侵入,但为了适应各种业务场景使用,需要严格遵循事务 ACID 特性;服务层更接近业务,可以针对不同业务做特定的优化处理,追求更高的极限性能。
当然,并不是说 XA 协议只能作用于单个服务内部的多资源场景,跨服务的多资源场景也是可以的,只不过同样需要额外的事务传递机制。
XA 协议通过每个 RM(Resource Manager,资源管理器)的本地事务隔离性来保证全局隔离,并且需要通过串行化隔离级别来保证分布式事务一致性。但是,串行化隔离级别存在一定的性能问题,如下所示:
在串行化隔离级别下,会为本来不加锁的 Select 快照读操作都加上读锁,导致锁持有时间增加,并发性能进一步降低。当实现了无锁的全局一致性读取后,比如分布式 MVCC,可以大幅减少锁持有时间,并发性能会获得较大提升。
但不管怎么优化实现,分布式事务的热点数据并发性能最高就是趋近于单机本地事务。所以,无论是基于 XA 协议实现的分布式事务,还是单机本地事务,都是存在热点数据并发性能极限的。
柔性事务
如果将实现了ACID
的事务要素的事务称为刚性事务的话,那么基于BASE
事务要素的事务则称为柔性事务。 BASE
是基本可用、柔性状态和最终一致性这三个要素的缩写。
- 基本可用(Basically Available)保证分布式事务参与方不一定同时在线。
- 柔性状态(Soft state)则允许系统状态更新有一定的延时,这个延时对客户来说不一定能够察觉。
- 而最终一致性(Eventually consistent)通常是通过消息可达的方式保证系统的最终一致性。
在ACID
事务中对隔离性的要求很高,在事务执行过程中,必须将所有的资源锁定。 柔性事务的理念则是通过业务逻辑将互斥锁操作从资源层面上移至业务层面。通过放宽对强一致性要求,来换取系统吞吐量的提升。
基于ACID
的强一致性事务和基于BASE
的最终一致性事务都不是银弹,只有在最适合的场景中才能发挥它们的最大长处。可通过下表详细对比它们之间的区别,以帮助开发者进行技术选型。
补偿事务(TCC)
TCC 是服务化的二阶段编程模型,采用的补偿机制:
条件:
- 需要实现确认和补偿逻辑
- 需要支持幂等
处理流程:
a) Try 阶段主要是对业务系统做检测及资源预留。
这个阶段主要完成: - 完成所有业务检查( 一致性 ) 。
- 预留必须业务资源( 准隔离性 ) 。
- Try 尝试执行业务。
b) Confirm 阶段主要是对业务系统做确认提交。
Try阶段执行成功并开始执行 Confirm阶段时,默认 Confirm阶段是不会出错的。即:只要Try成功,Confirm一定成功。
c) Cancel 阶段主要是在业务执行错误,需要回滚的状态下执行的业务取消,预留资源释放。
优点:
- 性能提升:具体业务来实现控制资源锁的粒度变小,不会锁定整个资源。
- 数据最终一致性:基于 Confirm 和 Cancel 的幂等性,保证事务最终完成确认或者取消,保证数据的一致性。
- 可靠性:解决了 XA 协议的协调者单点故障问题,由主业务方发起并控制整个业务活动,业务活动管理器也变成多点,引入集群。
缺点:TCC 的 Try、Confirm 和 Cancel 操作功能要按具体业务来实现,业务耦合度较高,提高了开发成本。
由于从业务服务是同步调用,其结果会影响到主业务服务的决策,因此通用型 TCC 分布式事务解决方案适用于执行时间确定且较短的业务,比如互联网金融企业最核心的三个服务:交易、支付、账务:
当用户发起一笔交易时,首先访问交易服务,创建交易订单;然后交易服务调用支付服务为该交易创建支付订单,执行收款动作,最后支付服务调用账务服务记录账户流水和记账。
为了保证三个服务一起完成一笔交易,要么同时成功,要么同时失败,可以使用通用型 TCC 解决方案,将这三个服务放在一个分布式事务中,交易作为主业务服务,支付作为从业务服务,账务作为支付服务的嵌套从业务服务,由 TCC 模型保证事务的原子性。
支付服务的 Try 接口创建支付订单,开启嵌套分布式事务,并调用账务服务的 Try 接口;账务服务在 Try 接口中冻结买家资金。一阶段调用完成后,交易完成,提交本地事务,由 TCC 框架完成分布式事务各从业务服务二阶段的调用。
支付服务二阶段先调用账务服务的 Confirm 接口,解冻买家资金;增加卖家可用资金。调用成功后,支付服务修改支付订单为完成状态,完成支付。
当支付和账务服务二阶段都调用完成后,整个分布式事务结束。
异步确保型 TCC 解决方案
异步确保型 TCC 解决方案的直接从业务服务是可靠消息服务,而真正的从业务服务则通过消息服务解耦,作为消息服务的消费端,异步地执行。
可靠消息服务需要提供 Try、Confirm、Cancel 三个接口。Try 接口预发送,只负责持久化存储消息数据;Confirm 接口确认发送,这时才开始真正的投递消息;Cancel 接口取消发送,删除消息数据。
消息服务的消息数据独立存储,独立伸缩,降低从业务服务与消息系统间的耦合,在消息服务可靠的前提下,实现分布式事务的最终一致性。
此解决方案虽然增加了消息服务的维护成本,但由于消息服务代替从业务服务实现了 TCC 接口,从业务服务不需要任何改造,接入成本非常低。
适用场景
由于从业务服务消费消息是一个异步的过程,执行时间不确定,可能会导致不一致时间窗口增加。因此,异步确保性 TCC 分布式事务解决方案只适用于对最终一致性时间敏感度较低的一些被动型业务(从业务服务的处理结果不影响主业务服务的决策,只被动的接收主业务服务的决策结果)。比如会员注册服务和邮件发送服务:
当用户注册会员成功,需要给用户发送一封邮件,告诉用户注册成功,并提示用户激活该会员。但要注意两点:
- 如果用户注册成功,一定要给用户发送一封邮件;
- 如果用户注册失败,一定不能给用户发送邮件。
因此,这同样需要会员服务和邮件服务保证原子性,要么都执行,要么都不执行。不一样的是,邮件服务只是一种被动型的业务,并不影响用户是否能够注册成功,它只需要在用户注册成功以后发送邮件给用户即可,邮件服务不需要参与到会员服务的活动决策中。
对于此种业务场景,可以使用异步确保型TCC分布式事务解决方案,如下:
由可靠消息服务来解耦会员和邮件服务,会员服务与消息服务组成 TCC 事务模型,保证事务原子性。然后通过消息服务的可靠特性,确保消息一定能够被邮件服务消费,从而使得会员与邮件服务在同一个分布式事务中。同时,邮件服务也不会影响会员服务的执行过程,只在会员服务执行成功后被动接收发送邮件的请求。
补偿型 TCC 解决方案
补偿型 TCC 解决方案与通用型 TCC 解决方案的结构相似,其从业务服务也需要参与到主业务服务的活动决策当中。但不一样的是,前者的从业务服务只需要提供 Do 和 Compensate 两个接口,而后者需要提供三个接口。
Do 接口直接执行真正的完整业务逻辑,完成业务处理,业务执行结果外部可见;Compensate 操作用于业务补偿,抵消或部分抵消正向业务操作的业务结果,Compensate操作需满足幂等性。
与通用型解决方案相比,补偿型解决方案的从业务服务不需要改造原有业务逻辑,只需要额外增加一个补偿回滚逻辑即可,业务改造量较小。但要注意的是,业务在一阶段就执行完整个业务逻辑,无法做到有效的事务隔离,当需要回滚时,可能存在补偿失败的情况,还需要额外的异常处理机制,比如人工介入。
- 适用场景
由于存在回滚补偿失败的情况,补偿型 TCC 分布式事务解决方案只适用于一些并发冲突较少或者需要与外部交互的业务,这些外部业务不属于被动型业务,其执行结果会影响主业务服务的决策,比如机票代理商的机票预订服务:
该机票服务提供多程机票预订服务,可以同时预订多趟行程航班机票,比如从北京到圣彼得堡,需要第一程从北京到莫斯科,以及第二程从莫斯科到圣彼得堡。
当用户预订机票时,肯定希望能同时预订这两趟航班的机票,只预订一趟航班对用户来说没有意义。因此,对于这样的业务服务同样提出了原子性要求,如果其中一趟航班的机票预订失败,另外一趟需要能够取消预订。
但是,由于航空公司相对于机票代理商来说属于外部业务,只提供订票接口和取消预订接口,想要推动航空公司改造是极其困难的。因此,对于此类业务服务,可以使用补偿型 TCC 分布式事务解决方案,如下:
网关服务在原有逻辑基础上增加 Compensate 接口,负责调用对应航空公司的取消预订接口。
在用户发起机票预订请求时,机票服务先通过网关 Do 接口,调用各航空公司的预订接口,如果所有航班都预订成功,则整个分布式事务直接执行成功;一旦某趟航班机票预订失败,则分布式事务回滚,由 TCC 事务框架调用各网关的 Compensate 补偿接口,其再调用对应航空公司的取消预订接口。通过这种方式,也可以保证多程机票预订服务的原子性。
---------------------------------
概念
XA是由X/Open组织提出的分布式事务的规范。XA规范主要定义了(全局)事务管理器(TM)和(局部)资源管理器(RM)之间的接口。主流的关系型数据库产品都是实现了XA接口的。
XA接口是双向的系统接口,在事务管理器(TM)以及一个或多个资源管理器(RM)之间形成通信桥梁。
XA之所以需要引入事务管理器是因为,在分布式系统中,从理论上讲两台机器理论上无法达到一致的状态,需要引入一个单点进行协调
由全局事务管理器管理和协调的事务,可以跨越多个资源(如数据库或JMS队列)和进程。全局事务管理器一般使用 XA 二阶段提交协议与数据库进行交互
两阶段提交(Two Phase Commit)
两阶段提交协议(Two-phase commit protocol)是XA用于在全局事务中协调多个资源的机制。
TM和RM间采取两阶段提交(Two Phase Commit)的方案来解决一致性问题。
两阶段提交需要一个协调者(TM)来掌控所有参与者节点(RM)的操作结果并且指引这些节点是否需要最终提交。
一、BASE理论
BASE
BA: Basic Availability 基本业务可用性(支持分区失败)
S: Soft state 柔性状态(状态允许有短时间不同步,异步)
E: Eventual consistency 最终一致性(最终数据是一致的,但不是实时一致)
原子性(A)与持久性(D)必须根本保障
为了可用性、性能与降级服务的需要,只有降低一致性( C ) 与 隔离性( I ) 的要求
酸碱平衡(ACID-BASE Balance)
二、CAP定理
定理: 对于共享数据系统,最多只能同时拥有CAP其中的两个,没法三者兼顾。
任两者的组合都有其适用场景
真实系统应当是ACID与BASE的混合体
不同类型的业务可以也应当区别对待
结论:分布式系统中,最重要的是满足业务需求,而不是追求抽象、绝对的系统特性
三、柔性事务
两阶段型
补偿型
异步确保型
最大努力通知型
四、柔性事务中的服务模式
可查询操作
幂等操作
TCC操作
可补偿操作
注:服务模式是柔性事务流程中的特殊操作实现(实现上对应业务服务要提供相应模式的功能接口),还不算是某一种柔性事务解决方案。
五、JavaEE平台中的分布式事务实现
JTA(Java Transaction API):面向应用、应用服务器与资源管理器的高层事务接口。
JTS(Java Transaction Service):JTA事务管理器的实现标准,向上支持JTA,向下通过CORBA OTS实现跨事务域的互操作性。
EJB:基于组件的应用编程模型,通过声明式事务管理进一步简化事务应用的编程。
优点
简单一致的编程模型
跨域分布处理的ACID保证
局限
DTP模型本身的局限
六、标准分布式事务解决方案的利弊
优点
严格的ACID
缺点
效率非常低(微服务架构下已不太适用)
全局事务方式下,全局事务管理器(TM)通过XA接口使用二阶段提交协议( 2PC )与资源层(如数据库)进行交互。使用全局事务,数据被Lock的时间跨整个事务,直到全局事务结束
2PC 是反可伸缩模式,在事务处理过程中,参与者需要一直持有资源直到整个分布式事务结束。这样,当业务规模越来越大的情况下,2PC 的局限性就越来越明显,系统可伸缩性会变得很差。
与本地事务相比,XA 协议的系统开销相当大,因而应当慎重考虑是否确实需要分布式事务。而且只有支持 XA 协议的资源才能参与分布式事务