Distributed Transaction - 分布式事务

注意
本文最后更新于 2022-11-08,文中内容可能已过时。

1. 3PC 相比 2PC 改进在哪?

3PC在事务管理者和事务参与者中引入了超时机制,超过响应时间默认失败,以避免事务参与者一直阻塞占用资源。(性能下降)在2PC中直邮事务管理者才拥有超时机制。 实际应用广泛的:2PC+复制状态机

2. TCC 与 2PC/3PC 的区别?

TCC :Try - Confirm - Cancel,一种柔性事务解决方案

  • 2PC/3PC 依靠数据库或者存储资源层面的事务,TCC 主要通过修改业务代码来实现。
  • 2PC/3PC 属于业务代码无侵入的,TCC 对业务代码有侵入
  • 2PC/3PC 追求的是强一致性,在两阶段提交的整个过程中,一直会持有数据库的锁。TCC 追求的

最终一致性,不会一直持有各个业务资源的锁。

3. 分布式事务分类:柔性事务和刚性事务

  • 柔性事务:TCC/FMT、Saga(状态机模式、Aop模式)、本地事务消息、消息事务(半消息)
    • 满足 BASE 理论
    • 有业务改造,最终⼀致性,实现补偿接⼝,实现资源锁定接⼝,⾼并发,适合⻓事务
    • 细分为两种:
      • 补偿型事务(同步):TCC、Saga
        • TCC 把事务运⾏过程分成 Try、Confirm / Cancel 两个阶段,每个阶段的逻辑由业务代码控制,避免了⻓事务,可以获取更⾼的性能。
      • 通知型事务(异步):MQ事务消息、最⼤努⼒通知型。
        • 外部系统:最大努力通知型因为外部的⽹络环境更加复杂和不可信,所以只能尽最⼤努⼒去通知实现数据最终⼀致性,⽐如充值平台与运营商、⽀付对接等等跨⽹络系统级别对接;
        • 内部系统:异步确保型,因为内部相对⽐较可控,如订单和购物⻋、收货与清算、⽀付与结算等等场景;
  • 刚性事务:XA 协议(2PC、JTA、JTS)、3PC
    • 满足 CP 理论
    • 通常⽆业务改造,强⼀致性,原⽣⽀持回滚/隔离性,低并发,适合短事务
    • 但由于同步阻塞,处理效率低,不适合⼤型⽹站分布式场景

最⼤努⼒通知事务 VS 异步确保型事务

最⼤努⼒通知事务在我认知中,其实是基于异步确保型事务发展⽽来适⽤于外部对接的⼀种业务实现。他们主要有的是业务差别,如下:

  • 从参与者来说:最⼤努⼒通知事务适⽤于跨平台、跨企业的系统间业务交互;异步确保型事务更适⽤于同⽹络体系的内部服务交付。
  • 从消息层⾯说:最⼤努⼒通知事务需要主动推送并提供多档次时间的重试机制来保证数据的通知;⽽异步确保型事务只需要消息消费者主动去消费。
  • 从数据层⾯说:最⼤努⼒通知事务还需额外的定期校验机制对数据进⾏兜底,保证数据的最终⼀致性;⽽异步确保型事务只需保证消息的可靠投递即可,⾃身⽆需对数据进⾏兜底处理。

4. 刚性事务 - XA 模型

这个模型主要使⽤了 2PC 来保证分布式事务的完整性。 在X/Open **DTP(Distributed Transaction Process)**模型⾥⾯,有三个⻆⾊:

  • AP: Application,应⽤程序。也就是业务层。哪些操作属于⼀个事务,就是AP定义的。
  • TM: Transaction Manager,事务管理器。接收AP的事务请求,对全局事务进⾏管理,管理事务分⽀状态,协调RM的处理,通知RM哪些操作属于哪些全局事务以及事务分⽀等等。这个也是整个事务调度模型的核⼼部分。
  • RM:Resource Manager,资源管理器。⼀般是数据库,也可以是其他的资源管理器,如消息队列(如JMS数据源),⽂件系统等。

XA规范主要定义了(全局)事务管理器(Transaction Manager)和(局部)资源管理器(Resource Manager)之间的接⼝。XA接⼝是双向的系统接⼝,在事务管理器(Transaction Manager)以及⼀个或多个资源管理器(Resource Manager)之间形成通信桥梁,从⽽在多个数据库资源下保证ACID四个特性。⽬前知名的数据库,如Oracle, DB2,mysql等,都是实现了XA接⼝的,都可以作为RM。 XA之所以需要引⼊事务管理器是因为,在分布式系统中,从理论上讲(参考Fischer等的论⽂),两台机器理论上⽆法达到⼀致的状态,需要引⼊⼀个单点进⾏协调。事务管理器控制着全局事务,管理事务⽣命周期,并协调资源。资源管理器负责控制和管理实际资源(如数据库或JMS队列)

5. XA规范

以下的函数使事务管理器可以对资源管理器进⾏的操作

  1. xa_open,xa_close:建⽴和关闭与资源管理器的连接。
  2. xa_start,xa_end:开始和结束⼀个本地事务。
  3. xa_prepare,xa_commit,xa_rollback:预提交、提交和回滚⼀个本地事务。
  4. xa_recover:回滚⼀个已进⾏预提交的事务。
  5. ax_开头的函数使资源管理器可以动态地在事务管理器中进⾏注册,并

可以对XID(TRANSACTION IDS)进⾏操作。

  1. ax_reg,ax_unreg;允许⼀个资源管理器在⼀个TMS(TRANSACTION

MANAGER SERVER)中动态注册或撤消注册。 XA各个阶段的处理流程

6. JTA规范

作为java平台上事务规范 JTA(Java Transaction API)也定义了对XA事务的⽀持,实际上,JTA是基于XA架构上建模的,在JTA 中,事务管理器抽象为javax.transaction.TransactionManager接⼝,并通过底层事务服务 (即JTS)实现。像很多其他的java规范⼀样,JTA仅仅定义了接⼝,具体的实现则是由供应商(如J2EE⼚商)负责提供。

7. TCC

TCC(Try-Confirm-Cancel)分布式事务模型相对于 XA 等传统模型,其特征在于它不依赖资源管理器(RM)对分布式事务的⽀持,⽽是通过对业务逻辑的分解来实现分布式事务。 TCC 模型认为对于业务系统中⼀个特定的业务逻辑,其对外提供服务时,必须接受⼀些不确定性,即对业务逻辑初步操作的调⽤仅是⼀个临时性操作,调⽤它的主业务服务保留了后续的取消权。如果主业务服务认为全局事务应该回滚,它会要求取消之前的临时性操作,这就对应从业务服务的取消操作。⽽当主业务服务认为全局事务应该提交时,它会放弃之前临时性操作的取消权,这对应从业务服务的确认操作。每⼀个初步操作,最终都会被确认或取消。 TCC 分布式事务模型包括三部分:

Try 阶段: 调⽤ Try 接⼝,尝试执⾏业务,完成所有业务检查,预留业务资源。 Confirm 或 Cancel 阶段: 两者是互斥的,只能进⼊其中⼀个,并且都满⾜幂等性,允许失败重试。 Confirm 操作: 对业务系统做确认提交,确认执⾏业务操作,不做其他业务检查,只使⽤ Try 阶段预留的业务资源。 Cancel 操作: 在业务执⾏错误,需要回滚的状态下执⾏业务取消,释放预留资源。

Try 阶段失败可以 Cancel,如果 Confirm 和 Cancel 阶段失败了怎么办?

TCC 中会添加事务⽇志,如果 Confirm 或者 Cancel 阶段出错,则会进⾏重试,所以这两个阶段需要⽀持幂等;如果重试失败,则需要⼈⼯介⼊进⾏恢复和处理等。

TCC事务模型的要求

  1. 可查询操作:服务操作具有全局唯⼀的标识,操作唯⼀的确定的时间。
  2. 幂等操作:重复调⽤多次产⽣的业务结果与调⽤⼀次产⽣的结果相同。
    1. 通过业务操作实现幂等性
    2. 系统缓存所有请求与处理的结果,最后是检测到重复请求之后,⾃动返回之前的处理结果。

TCC事务模型 VS DTP事务模型

⽐较⼀下TCC事务模型和DTP事务模型,如下所示:

这两张图看起来差别较⼤,实际上很多地⽅是类似的!

  1. TCC模型中的 主业务服务 相当于 DTP模型中的AP,TCC模型中的从业务服务 相当于 DTP模型中的RM

在DTP模型中,应⽤AP操作多个资源管理器RM上的资源;⽽在TCC模型中,是主业务服务操作多个从业务服务上的资源。例如航班预定案例中,美团App就是主业务服务,⽽川航和东航就是从业务服务,主业务服务需要使⽤从业务服务上的机票资源。不同的是DTP模型中的资源提供者是类似于Mysql这种关系型数据库,⽽TCC模型中资源的提供者是其他业务服务。

  1. TCC模型中,从业务服务提供的try、confirm、cancel接⼝ 相当于 DTP模型中RM提供的prepare、commit、rollback接⼝。XA协议中规定了DTP模型中定RM需要提供prepare、commit、rollback 接⼝给TM调⽤,以实现两阶段提交。⽽在TCC模型中,从业务服务相当于RM,提供了类似的try、confirm、 cancel接⼝。
  2. 事务管理器:DTP模型和TCC模型中都有⼀个事务管理器。不同的是:在DTP模型中,阶段1的(prepare)和阶段2的(commit、rollback),都是由TM进⾏调⽤的。在TCC模型中,阶段1的try接⼝是主业务服务调⽤(绿⾊箭头),阶段2的(confirm、cancel接⼝)是事务管理器TM调⽤(红⾊箭头)。这就是 TCC 分布式事务模型的⼆阶段异步化功能,从业务服务的第⼀阶段执⾏成功,主业务服务就可以提交完成,然后再由事务管理器框架异步的执⾏各从业务服务的第⼆阶段。这⾥牺牲了⼀定的隔离性和⼀致性的,但是提⾼了⻓事务的可⽤性。

TCC与2PC对⽐

  • XA是资源层⾯的分布式事务,强⼀致性,在两阶段提交的整个过程中,⼀直会持有资源的锁。基于数据库锁实现,需要数据库⽀持XA协议,由于在执⾏事务的全程都需要对相关数据加锁,⼀般⾼并发性能会⽐较差
  • TCC是业务层⾯的分布式事务,最终⼀致性,不会⼀直持有资源的锁,性能较好。但是对微服务的侵⼊性强,微服务的每个事务都必须实现try、confirm、cancel等3个⽅法,开发成本⾼,今后维护改造的成本也⾼为了达到事务的⼀致性要求,try、confirm、cancel接⼝必须实现幂等性操作由于事务管理器要记录事务⽇志,必定会损耗⼀定的性能,并使得整个TCC事务时间拉⻓。TCC它会弱化每个步骤中对于资源的锁定,以达到⼀个能承受⾼并发的⽬的(基于最终⼀致性)。

TCC 的使⽤场景

TCC是可以解决部分场景下的分布式事务的,但是,它的⼀个问题在于,需要每个参与者都分别实现Try,Confirm和Cancel接⼝及逻辑,这对于业务的侵⼊性是巨⼤的。 TCC ⽅案严重依赖回滚和补偿代码,最终的结果是:回滚代码逻辑复杂,业务代码很难维护。所以,TCC ⽅案的使⽤场景较少,但是也有使⽤的场景。 ⽐如说跟钱打交道的,⽀付、交易相关的场景,⼤家会⽤ TCC⽅案,严格保证分布式事务要么全部成功,要么全部⾃动回滚,严格保证资⾦的正确性,保证在资⾦上不会出现问题。

0%