分布式事务原理及解决方案,这一篇足矣

目录

分布式事务原理及解决方案

MySQL 分布式原理

事务的定义

解决方案

1. 2PC(基于MySQL XA)

2. 3PC (XA)

3. TCC

4. RocketMQ 消息队列

5. Seata (TM、RM 和 TC)


分布式事务原理及解决方案

MySQL 分布式原理

在 MySQL 中,使用分布式事务的应用程序设计一个或者多个资源管理器和一个事务管理器。

  • 资源管理器(RM)用于提供通向事务资源的途径。数据库服务器是一种资源管理器。该管理器必须可以提交或回滚由 RM 管理的事务。例如,多台 MySQL数据库作为多台资源管理器或者几台 Mysql 服务器和几台 ORACLE 服务器作为资源管理器。

  • 事务管理器(TM)用于协调作为一个分布式事务一部分的事务。TM 与管理每个事务的 RMs 进行通讯。一个分布式事务中各个单个事务均是分布式事务的 ”分支事务“。分布式事务和各分支通过一种命名方法进行标识。

MySQL 执行 XA MySQL 时,MySQL 服务器相当于一个用于管理分布式事务中的 XA 事务 的资源管理器。与 MySQL 服务器连接的客户端相当于事务管理器。

用于执行分布式事务的过程使用两阶段提交,发生时间在由分布式事务的各个分支需要 进行的行动已经被执行之后。

  • 在第一阶段,所有的分支被预备好。即它们被 TM 告知要准备提交。通常,这意味 着用于管理分支的每个 RM 会记录对于被稳定保存的分支的行动。分支指示是否它们可以这 么做。这些结果被用于第二阶段。

  • 在第二阶段,TM 告知 RMs 是否要提交或回滚。如果在预备分支时,所有的分支指 示它们将能够提交,则所有的分支被告知要提交。如果在预备时,有任何分支指示它将不能 提交,则所有分支被告知回滚。

事务的定义

  • 原子性(Atomicity),可以理解为一个事务内的所有操作要么都执行,要么都不执行。

  • 一致性(Consistency),可以理解为数据是满足完整性约束的,也就是不会存在中间状态的数据,比如你账上有400,我账上有100,你给我打200块,此时你账上的钱应该是200,我账上的钱应该是300,不会存在我账上钱加了,你账上钱没扣的中间状态

  • 隔离性(Isolation),指的是多个事务并发执行的时候不会互相干扰,即一个事务内部的数据对于其他事务来说是隔离的。

  • 持久性(Durability),指的是一个事务完成了之后数据就被永远保存下来,之后的其他操作或故障都不会对事务的结果产生影响。

而通俗意义上事务就是为了使得一些更新操作要么都成功,要么都失败。

解决方案

1. 2PC(基于MySQL XA)

XA 是两阶段提交,XA START xid 用于启动一个带给定 xid 值的 XA 事务。每个 XA 事务必须有一个唯一的 xid 值,因此该值当前不能被其他的 XA 事务使用。xid 是一个 XA 事务标识符,用来唯一标识一个分布式事务。xid 值由客户端提供,或由 MySQL 服务器生成。xid 值包含 1~3 个部分:xid: gtrid [, bqual [, formatID ]]

  • gtrid 是一个分布式事务标识符,相同的分布式事务应该使用相同的 gtrid,这样可以 明确知道 xa 事务属于哪个分布式事务。

  • bqual 是一个分支限定符,默认值是空串。对于一个分布式事务中的每个分支事务, bqual 值必须是唯一的。

  • formatID 是一个数字,用于标识由 gtrid 和 bqual 值使用的格式,默认值是 1。

两阶段提交分为 prepare、commit 阶段。第一阶段确保每个分支上的事务都进行提交,进入 prepare 状态。两个事务都进入准备提交阶段,如果之前遇到任何错误,都应该回滚所有的分支,以确保分布式事务的正确。两个事务都到达准备提交阶段后,一旦开始进行提交操作,就需要确保全部的分支都提交成功。

image-20210405223709653

存在问题

同步阻塞:当参与事务者存在占用公共资源的情况,其中一个占用了资源,其他事务参与者就只能阻塞等待资源释放,处于阻塞状态。

单点故障:一旦事务管理器出现故障,整个系统不可用

在阶段二,如果事务管理器只发送了部分 commit 消息,此时网络发生异常,那么只有部分参与者接收到 commit 消息,也就是说只有部分参与者提交了事务,使得系统数据不一致。

不确定性:当协事务管理器发送 commit 之后,并且此时只有一个参与者收到了 commit,那么当该参与者与事务管理器同时宕机之后,重新选举的事务管理器无法确定该条消息是否提交成功。

2. 3PC (XA)

相比于XA,3PC把2PC的准备阶段再次进行拆分,并且3PC引入了参与者超时机制。

  • canCommit:协调者询问参与者,是否具备执行事务的条件,参与者进行自身事务必要条件的检查;

  • preCommit:协调者通知参与者进行事务的预提交;

  • doCommit:协调者根据preCommit阶段参与者的反馈结果通知参与者是否进行事务提交或是进行事务回滚;

image-20210405221000923

2PC 3PC 区别

  1. 阶段的区别

    • 2PC 是 提交事务请求以及执行事务提交

    • 3PC 将 2PC 的提交事务请求分成了CanCommit以及PreCommit(不是某些网上说的“3PC的CanCommit阶段其实和2PC的准备阶段很像”,就是一部分而已)

  2. 超时判断

    • 3PC 在协调者、参与者中都加入了超时判断机制,2PC 只有协调者有。

    • 加入的超时机制在某种程度上解决了2PC 的 单点、阻塞问题。

    • 没有真正解决单点问题。阻塞的问题

  3. 3PC 在 commit 之前增加了 preCommit 的过程,使得在参与者在收不到确认时,依然可以从容 commit 或者 rollback,避免资源锁定太久导致浪费。但是 3PC 同样存在着很多问题。实现起来非常复杂,因为很难通过多次询问来解决系统间分歧问题,尤其是存在超时状态互不信任的分布式网络中,这也就是著名的拜占庭将军问题

3. TCC

TCC(Try-Confirm-Cancel)又称补偿事务。主要是用户业务层面,而XA、2PC、3PC 主要是数据库层面的。其核心思想是:“针对每个操作都要注册一个与其对应的确认和补偿(撤销操作)”。TCC 事务机制相比于上面介绍的 XA,解决了其几个缺点:

  • 解决了协调者单点,由主业务方发起并完成这个业务活动。业务活动管理器也变成多点,引入集群。

  • 同步阻塞:引入超时,超时后进行补偿,并且不会锁定整个资源,将资源转换为业务逻辑形式,粒度变小。

  • 数据一致性,有了补偿机制之后,由业务活动管理器控制一致性

    具体步骤

TCC(Try Confirm Cancel) Try 阶段:尝试执行,完成所有业务检查(一致性), 预留必须业务资源(准隔离性) Confirm 阶段:确认执行真正执行业务,不作任何业务检查,只使用 Try 阶段预留的业务资源,Confirm 操作满足幂等性。要求具备幂等设计,Confirm 失败后需要进行重试。 Cancel 阶段:取消执行,释放 Try 阶段预留的业务资源 Cancel 操作满足幂等性 Cancel 阶段的异常和 Confirm 阶段异常处理方案基本上一致。

在 Try 阶段,是对业务系统进行检查及资源预览,比如订单和存储操作,需要检查库存剩余数量是否够用,并进行预留,预留操作的话就是新建一个可用库存数量字段,Try 阶段操作是对这个可用库存数量进行操作。 基于 TCC 实现分布式事务,会将原来只需要一个接口就可以实现的逻辑拆分为 Try、Confirm、Cancel 三个接口,所以代码实现复杂度相对较高。

image-20210405215759542

4. RocketMQ 消息队列

第一步先给 Broker 发送事务消息即半消息,半消息不是说一半消息,而是这个消息对消费者来说不可见,然后发送成功后发送方再执行本地事务

再根据本地事务的结果向 Broker 发送 Commit 或者 RollBack 命令

并且 RocketMQ 的发送方会提供一个反查事务状态接口,如果一段时间内半消息没有收到任何操作请求,那么 Broker 会通过反查接口得知发送方事务是否执行成功,然后执行 Commit 或者 RollBack 命令。

如果是 Commit 那么订阅方就能收到这条消息,然后再做对应的操作,做完了之后再消费这条消息即可。

如果是 RollBack 那么订阅方收不到这条消息,等于事务就没执行过。如果出现了B系统消费失败,那么就进行重试,重试到一定次数那便将记录到本地消息表中,方便人工进行排查。

image-20210405222432818

5. Seata (TM、RM 和 TC)

Seata 中有三大模块,分别是 TM、RM 和 TC。 其中 TM 和 RM 是作为 Seata 的客户端与业务系统集成在一起,TC 作为 Seata 的服务端独立部署。

在 Seata 中,分布式事务的执行流程:

  • TM 开启分布式事务(TM 向 TC 注册全局事务记录);

  • 按业务场景,编排数据库、服务等事务内资源(RM 向 TC 汇报资源准备状态 );

  • TM 结束分布式事务,事务一阶段结束(TM 通知 TC 提交/回滚分布式事务);

  • TC 汇总事务信息,决定分布式事务是提交还是回滚;

  • TC 通知所有 RM 提交/回滚 资源,事务二阶段结束;

猜你喜欢

转载自blog.csdn.net/LarrYFinal/article/details/115450079