深入理解分布式事务-原理与实践-分布式事务基础


分布式事务基础

事务的基本概念

ACID

  1. 原子性
  2. 一致性
  3. 隔离性
  4. 持久性

事务的类型

  • 扁平事务
    事务操作中最常见、最简单的事务,无法单独提交整个事务中的部分事务,只能把整个事务全部提交或者回滚;

  • 带有保存点的扁平事务
    内部带有保存点的事务,可以将当前事务回滚到此位置;

  • 链式事务
    链式事务是在带有保存点的扁平事务的基础上,自动将当前事务的上下文隐式的传递给下一事务,也就是说一个事务的提交操作和下一个事务的开始操作合并在一起是具备原子性的;

  • 嵌套事务
    嵌套事务指的是有多个事务处于嵌套状态,共同完成一项任务的处理,整个任务具备原子性;嵌套事务最外层有一个顶层事务,只有当顶层事务完成后才会整体提交;

  • 分布式事务基础
    分布式事务指的是事务的参与者、事务所在的服务器、涉及的资源服务器以及事务管理器分别位于不同的分布式系统下的一个整体事务;

本地事务

本地事务通常是由关系型数据库本身的事务特性来进行实现的,优缺点:

优点:

  1. 严格支持ACID特性
  2. 事务可靠,关系型数据的事务是经过严格论证的
  3. 本地事务执行效率高
  4. 事务是由DBMS完成
  5. 不涉及网络通信

缺点:

  1. 不具备分布式事务的处理能力
  2. 一次事务处理过程只能连接一个支持事务的数据库,即不能用于多个事务性数据库;

MySql事务基础

  • 并发带来的问题
  1. 更新丢失
    丢失更新本质上是写操作冲突,解决的方法是让每个事务按照一定的顺序进行写操作;
  2. 脏读
    脏读本质上是读写操作冲突,解决的方法是先写后读,写完之后才能读取;
  3. 不可重复读
    不可重复读本质上是读写操作冲突,解决的方法是先读后写,读完之后才能进行写入操作;
  4. 幻读
    幻读本质上是读写操作冲突,解决的方法是先读后写,读完之后才能进行写入操作;

不可重复读幻读的区别在于,不可重复读关注的是对字段的更新或删除操作,幻读的重点是在于插入操作;

  • MySQL事务隔离级别
  1. 读未提交
  2. 读已提交
  3. 可重复读
  4. 串行化

MySQL的默认事务隔离级别是可重复读,MySQL用MVCC机制保证的在克重复读级别下不会出现脏读<B>不可重复读<B>幻读,其中幻读是通过间隙锁来解决的;

  • MySQL中锁的分类

MySQL中锁的分类

读锁和写锁是互斥的,读锁和读锁不互斥,写锁和写锁是互斥的;
避免死锁的几种方式:

  1. 尽量让 数据表中的数据检索都通过索引的方式来完成,避免无效索引导致行锁升级为表锁;
  2. 合理设计索引,尽量缩小锁的范围;
  3. 尽量减少查询条件的范围,尽量避免间隙锁或缩小间隙锁的范围;
  4. 尽量控制事务的大小,减少一次事务锁定的资源数量,缩短锁定资源的时间;
  5. 如果一条SQL语句涉及事务加锁操作,则尽量将其放到最后,从而减少锁定资源的时间;
  • InnoDB的MVCC的原理

通过在数据行上定义两个字段:分别是创建行版本号<B>删除行版本号,这两个版本号只标识该行的创建和该行的删除动作的时序;

  1. 查询操作

InnoDB存储引擎只会查询版本号小于或者等于当前查询事务版本号的数据行,这样做的目的是在于只能查询到当前事务开始时那一刻的数据,或者当前事务修改的数据行,并且会判断删除版本号是否大于当前事务ID;

  1. 插入操作

在插入数据时根据当前事务的版本号来维护数据行上的创建版本号,插入操作不维护删除版本号

  1. 更新操作

更新操作是在数据行上将上一条数据的删除版本号更新为当前更新操作的事务版本号,然后重新复制出一条新的数据行,其中创建版本号为当前更新事务的版本号;

  1. 删除操作

删除操作是更新最新的数据行上的DB_DELETED(删除行版本号)

MySQL事务的实现原理

MySQL的事务实现是由于锁\MVCC\Redo Log\Undo Log共同来完成的,其中事务的隔离性是通过锁和MVCC机制,原子性和持久性是通过Redo Log,一致性是通过Undo Log来实现的;

Redo Log

Redo Log向前,记录的是InnoDB执行的动作的日志,也被称为重做日志,用于故障恢复和保证事务的原子性和持久性;
Redo Log的日志记录格式是物理日志,记录的是磁盘上数据进行的修改操作;

其中对于Redo Log写入文件的刷盘时机有以下几种规则:

  1. 由inboodb_flush_log_at_trx_commit配置决定:设置为0或者2时每秒去刷盘,区别在于是否需要通过Log Buffer,设置为1时是每次事务提交时进行刷盘
  2. 每秒刷新一次
  3. Log Buffer内存使用超过一半时
  4. 当事务中存在checkpoint(检测点),checkpoint机制去刷新脏页

Undo Log

Undo Log是用于回滚事务和实现MVCC机制的,采用的是和操作相反的逻辑格式记录日志;
Undo Log的回滚段分 为insert undo log和update undo log;
insert undo log指的是事务对插入新记录产生的Undo log,只作用于事务回滚时需要,在事务提交后即可丢弃;
update undo log指的是事务对记录进行删除和更新操作时产生的Undo log日志,作用于事务回滚以及一致性读,只有当所有的事务id大于该版本时才能进行删除;

Bin Log

Bin log是MySQL用于主从复制和故障恢复的日志格式,其中记录格式分为Row格式<B>Statement格式<B>Mixed模式;

Row格式:保存的是对数据的修改
Statement格式:保存的是执行SQL
Mixed格式:默认是Statement,对于无法使用Statemnt格式的采用Row格式

MySQL事务在提交的时候会记录事务日志和二进制日志,是先记录二进制日志在写入事务日志;
两者配合完成了事务的一致性,采用的二阶段提交流程如下所示:

  1. Prepare阶段
    a. BinLog Buffer
    b. RedoLog Buffer -> RedoLog file(prepare标识)
  2. Commit 阶段
    a. BinLog Buffer -> BinLog file
    b. RedoLog file(prepare标识) -> RedoLog file(commit标识)

MySQL事务流程

  • MySQL事务执行流程

MySQL事务执行流程

在这个流程中,第4个步骤是记录Undo Log对应的Redo Log到内存缓冲区,因为Undo Log的操作也需要Redo Log进行记录

  • MySQL事务恢复流程
  1. 在事务执行到第8步时,MySQL崩溃或者宕机,会优先使用Redo Log恢复数据,然后使用Undo Log回滚数据;
  2. 如果执行到第8步之后,MySQL崩溃或宕机,会使用Redo Log恢复数据;

MySQL事务恢复流程

大体上可以划分为两个阶段:提交事务和回滚事务,其中提交事务是提交Redo Log已经标记为成功的事务,回滚事务是回滚Redo Log中未提交的事务,同时需要配合bin log完成写入;

MySQL中的XA事务

XA分布式事务的全称是 eXtended Architecture Transaction,XA事务支持不同的数据库实例共同完成分布式事务;
XA事务的本质是一种基于两阶段提交的分布式事务,在使用XA分布式事务时,需要将InnoDB存储引擎的事务隔离级别设置为串行化;

XA事务模型

参与者:

  1. 事务管理器
    主要对参与全局事务的各个分支事务进行协调,并对资源管理器进行通信;通常是一个单独的应用服务器或者中间件,例如JTA;

  2. 资源管理器
    资源管理器通常是数据库实例

  3. 应用程序
    主要用来发起全局事务和分支事务的操作

XA事务的执行流程

XA事务是一个两阶段提交的分布式事务,大体的流程分为Prepare阶段Commit阶段

  • Prepare阶段
  1. 事务管理器™开启一个全局事务,该全局事务具有一个唯一的全局事务ID(XID)
  2. 事务管理器™通知各个资源管理器(RM)开启一个各自的新事务
  3. 资源管理器(RM)开始执行各自的事务分支,只写入不进行提交,处于事务已开启-未提交状态,注意这一步是锁定住资源的
  4. 资源管理器(RM)向事务管理器™上报Prepare阶段的执行结果
  • Commit阶段
  1. 事务管理器™收集所有资源管理器(RM)的Prepare阶段的结果,超时会认为是失败
  2. 事务管理器™收集所有资源管理器(RM)的结果,确认Commit阶段下发的命令是Commit还是Rollback
  3. 资源管理器(RM)根据事务管理器™的结果完成Commit或者Rollback
  4. 资源管理器(RM)向事务管理器™上报第二个步骤的执行结果

XA事务超时的处理策略

  • Prepare阶段
  1. TM超时回滚机制
  2. TM超时下发全局回滚
  3. RM自行回滚
  • Commit阶段
  1. TM重试机制
  2. RM的幂等性保证
  3. 回滚补偿

XA事务的性能问题

  1. 阻塞性(Blocking)
    在准备阶段(Prepare),资源管理器(RM)需要开始锁定资源
  2. 网络开销
    2PC 协议需要进行多次网络通信
  3. 复杂性和单点问题
    TM\RM\APP等多个组件带来的复杂性,TM会带来单点问题

XA事务的优点

  1. 强一致性的分布式事务解决方案

Spring事务的实现原理

Spring事务原理

Spring实现事务的原理是关闭自动提交;

Spring事务的三大接口

Spring支持事务管理功能,最核心的就是Spring事务的三大接口:PlatformTransactionManagerTransactionDefinitionTransactionStatus

  • PlatformTransactionManager
    Spring不是直接管理事务,而是定义提供多种事务管理器,通过这些事务管理器将事务管理的职责委托给Hibernate\MyBatis\JPA等持久化框架;
    PlatformTransactionManager就是定义事务操作的基本方法类,为Spring提供了一个统一的事务管理接口,类似于桥接的设计模式;
    Spring_PlatformTransactionManager_类图

  • TransactionDefinition
    TransactionDefinition接口主要用来定义与事务相关的方法,表示事务属性的常量信息

Spring_TransactionDefinition_类图


public interface TransactionDefinition {

	/**
	 * 支持当前事务,如果当前没有事务就创建一个新事务
	 */
	int PROPAGATION_REQUIRED = 0;

	/**
	 * 如果当前存在事务,即加入该事务;如果当前不存在事务,即以非事务的方式运行
	 */
	int PROPAGATION_SUPPORTS = 1;

	/**
	 * 如果当前存在事务,即加入该事务;如果当前不存在事务,立即抛出异常
	 */
	int PROPAGATION_MANDATORY = 2;

	/**
	 * 创建一个新事务运行,如果当前存在事务,挂起当前已存在的事务
	 */
	int PROPAGATION_REQUIRES_NEW = 3;

	/**
	 * 以非事务的方式运行,如果当前存在事务,挂起当前已存在的事务
	 */
	int PROPAGATION_NOT_SUPPORTED = 4;

	/**
	 * 以非事务的方式运行,如果当前存在事务,立即抛出异常
	 */
	int PROPAGATION_NEVER = 5;

	/**
	 * 如果当前存在事务,则创建一个嵌套事务;如果当前没有事务,则创建一个新的事务
	 */
	int PROPAGATION_NESTED = 6;

	/**
	 * 使用后端数据库默认的隔离级别
	 */
	int ISOLATION_DEFAULT = -1;

  //后续还有事务隔离级别\传播行为\超时时间等定义
  • TransactionStatus
    TransactionStatus接口主要用来存储事务的执行状态,定义了一组方法,用来读取事务的状态信息;

Spring_TransactionStatus_类图

Spring事务隔离级别

Spring中事务存在五种隔离级别:ISOLATION_DEFAULTISOLATION_READ_UNCOMMITTEDISOLATION_READ_COMMITTEDISOLATION_REPEATABLE_READISOLATION_SERIALIZABLE

隔离级别 脏读 不可重复读 幻读 并发性能 数据一致性
ISOLATION_READ_UNCOMMITTED 最高 最差
ISOLATION_READ_COMMITTED 较高 较差
ISOLATION_REPEATABLE_READ 较低 较好
ISOLATION_SERIALIZABLE 最低 最好

这里需要注意的是Spring 事务隔离级别和数据库事务隔离级别是协同工作的。 Spring 负责发起隔离级别请求,而数据库负责实现。 最终起作用的是数据库的隔离级别。 因此,了解数据库的隔离级别支持和默认设置非常重要。 通过显式配置 Spring 的隔离级别并在不同的数据库环境下进行测试,可以确保事务隔离的正确性。

Spring的事务管理器会使用JDBC驱动请求设置数据库的隔离级别,但是是需要数据库支持才可以,如果数据库忽略设置隔离级别,对于Spring事务管理器来说也无可奈何;

Spring事务传播机制

类别 事务传播机制类型 描述
支持当前事务的传播机制 REQUIRED 尝试加入现有事务或创建新的事务
_ SUPPORTS 尝试加入现有事务或以非事务的方式执行
_ MANDATORY 尝试加入现有事务,失败则抛出异常
不支持当前事务的传播机制 REQUIRES_NEW 创建新的事务,挂起现有事务
_ NOT_SUPPORTED 挂起现有事务后以非事务的方式执行
_ NEVER 抛出异常
嵌套事务 NESTED 创建嵌套事务(保存点),加入现有事务。外部事务回滚,内部事务也会回滚

最常用的事务传播机制:

  1. REQUIRED
    默认事务传播机制,适用于大部分场景
  2. NOT_SUPPORTED
    非事务执行的场景,适用于允许以非事务执行的场景
  3. REQUIRED_NEW
    适用于需要以事务方式保证持久化但是又不需要被外层事务所影响的场景,例如记录操作日志,即使主业务流程失败,也需要记录本次操作的场景

Spring事务失效的场景

  1. 方法没有被public修饰
    由于Spring是通过AOP的方式织入的开启事务和提交事务的,因此方式是非public的时无法代理

  2. 同一个类中直接调用
    直接调用,不经过AOP,无法开启事务;

  3. 使用不支持事务的传播机制
    例如NOT_SUPPORTED这种不开启事务的机制

  4. 错误的catch异常/标注错误的异常类型
    由于事务的回滚需要依赖方法抛出异常,如果吃掉异常,那么就不会回滚事务,这时需要判断是否符合业务逻辑;
    Spring中默认回滚的异常为RuntimeException,如果抛出其他异常时,需要使用rollbackFor进行标识

分布式事务的基本概念

  • 架构目标和架构原则
  1. N+1设计
  2. 回滚设计
  3. 禁用设计
  4. 监控设计
  5. 设计多活数据中心
  6. 使用成熟的技术
  7. 异步设计
  8. 无状态系统
  9. 水平扩展而非垂直升级
  10. 设计时至少要有两步前瞻性
  11. 非核心则购买
  12. 使用商品化硬件
  13. 小构建\小发布\快速试错
  14. 故障隔离
  15. 自动化

《The Art of Scalability》一书的观点很赞👍,这本书需要看;

分布式事务场景

  1. 跨JVM进程

分布式事务基础_跨JVM调用场景

  1. 同一应用调用多个数据库实例场景
    分布式事务基础_跨数据库调用场景

  2. 多个应用调用同一个数据库实例场景
    分布式事务基础_多个服务调用同一数据库场景

数据一致性

数据一致性问题,包括数据多副本\调用超时\缓存与数据库不一致\多个缓存节点内数据不一致等问题;
常用的解决方案有:ACID特性\CAP理论\Base理论\DTP理论\2PC(两阶段提交)\3PC(三阶段提交)\TCC模型\可靠消息最终一致性模型\最大努力通知模型等;

分布式事务的理论基础

CAP理论

CAP指的是Consistency(一致性)、Availability(可用性)、Partition tolerance(分区容错性),这三个分布式系统中最重要的三个需求;
由于三者最多只能满足两点,因此有AP\CP\CA,这三种模式:

  1. AP模式
    指的是追求系统的可用性和分区容忍性,由于分区容忍性在现实场景中很难避免,因此现在一致性还是可用性,是一种架构上的选择;Base理论就是基于AP模式的衍生
  2. CP模式
    强一致性,代表系统有ZK
    3.AC
    放弃分区容忍性,架构回滚为单体应用架构

Base理论

Base理论是AP模式的扩展,由于CAP中的一致性指的是强一致性,是在任何时间读取任意节点的数据都必须是一致,而Base理论中的一致性指的是允许在某一段时间内数据不一致,但是最终都非达到一致;

分布式事务的解决方案

强一致性的分布式事务解决方案

强一致性的分布式事务解决方案主要有DTP模型2PC模型3PC模型,要求在任意时刻查询参与全局事务的各个节点的数据都是一致的;

  • 优缺点
    优点如下:
  1. 数据一致性比较高
  2. 在任意时刻都能够查询到最新写入的数据

缺点如下:

  1. 存在性能问题,在分布式事务未完全提交和回滚之前,应用程序查询不到最新的数据
  2. 实现复杂
  3. 牺牲了可用性
  4. 不适合高并发的场景

DTP模型

DTP模型是由X/Open组织定义的一套分布式事务标准,这套标准主要定义实现分布式事务的规范和API,具体的实现交给相应的厂商来进行实现,类似JDBC驱动,由不同的数据库厂商进行实现;常见的实现有MySQL的XA模式、

  • DTP模型定义的重要概念
  1. 事务:一个事务就是一个完整的工作单元,应具备特性
  2. 全局事务:由事务管理器管理的事务,能够一次性操作多个资源管理器
  3. 分支事务:每个资源管理器中独立的事务
  4. 控制线程:执行全局事务的线程,这个线程用于协调关联应用程序\事务管理器\资源管理器等,又被称为事务上下文环境
  • DTP模型的四大组件
组件 全称 作用
AP Application Program 事务发起者,调用事务服务
TM Transaction Manager 控制事务的全局一致性(如开启、提交、回滚事务)
RM Resource Manager 资源管理器,如数据库、消息中间件等,执行具体的事务操作
CM Communication Resource Manager 通信管理器,负责不同节点间的通信(有时合并在 RM 或 TM 中)
  • DTP模型示意图

DTP模型示意图

这个模型可以被划分为两个阶段:

  1. Prepare阶段
    这个阶段包括步骤(1,2,3,4,5,6,7,8),其中步骤3\5开始进行RM分支事务,只会修改数据但是不会提交事务,同时记录Redo Log和Undo Log,后续步骤7和步骤8指的是更新数据和记录日志的操作以及锁定资源;

  2. Commit阶段
    步骤9和步骤10是RM接收到TM的命令后开始通过Redo Log刷盘或者Undo Log回滚,并释放资源;

从上述步骤中可以看到DTP模型中的强一致性是通过长时间锁定资源来进行实现的,实际生产中可能会产生问题;

2PC模型

2PC模型指的是两阶段提交协议,P-Prepare阶段、C-Commit阶段;其中XA模型是2PC模型的一个具体实现;

  • 2PC模型存在的问题
  1. 同步阻塞问题:在事务执行过程中,所有参与事务的节点都会对其占用的公共资源进行加锁,导致其他访问该公共资源的进程或者线程阻塞;
  2. 单点故障问题:事务管理器™发生故障时,资源管理器(RM)会一直阻塞
  3. 数据不一致问题:在Commit阶段,如果TM发送的指令丢失,会导致资源管理器中的数据库可能与其他RM中的数据不一致
  4. 在Commit阶段,如果TM发送完成Commit信息后宕机,然后RM宕机,导致无法确认事务是否已提交,RM有可能提交也有可能不提交;

3PC模型

3PC模型指的是三阶段提交模型,是为了解决2PC模型中的一些问题也提出来的,主要是将2PC模型中的Prepare阶段划分为CanCommit阶段PreCommit阶段Commit阶段;3PC 引入了超时机制和预提交阶段,从而降低了阻塞发生的概率;

  • CanCommit阶段
    准备阶段是事务管理器向所有参与者发送CanCommit请求,询问它们是否可以执行提交操作;

3PC_CanCommit阶段

3PC 模型中 CanCommit 阶段的主要目的是在更早的阶段让参与者 (Participants,即资源管理器) 有机会拒绝事务,从而避免后续阶段可能发生的阻塞和资源浪费;

  1. 降低阻塞的可能性
    3PC 模型引入了 CanCommit 阶段,允许参与者在收到 Prepare 命令之前,先检查自身的状态,判断是否能够提交事务。 如果参与者发现无法提交,则可以直接拒绝事务,从而避免了后续 Prepare 和 Commit 阶段的资源浪费和可能的阻塞

  2. 提前发现问题,减少资源占用
    CanCommit 阶段发现问题,参与者可以拒绝事务,从而释放占用的资源,避免后续阶段的资源浪费;

  3. 提高系统的响应速度
    通过在早期阶段过滤掉无法提交的事务,可以减少后续阶段的处理量,从而提高系统的整体响应速度。
    如果协调者在 CanCommit 阶段收到多个参与者的 No 响应,它可以立即中止事务,避免后续不必要的处理。

  4. 作为协调者和参与者之间的一次心跳检测

执行失败处理机制

在CanCommit阶段有RM执行失败,在这个阶段中TM会向参与全局事务的资源管理器(RM)发送CanCommit请求,如果不能执行完成事务,则会向事务管理器响应No状态,TM收到NO响应,就中断全局事务的继续执行;

  • PreCommit阶段

3PC_PreCommit阶段

3PC 模型中 PreCommit 阶段的主要目的是让资源管理器开始执行事务操作,同时将Undo Log和Redo Log信息写入事务日志中,并向事务管理器™发送执行的ACK状态,此时不会提交事务

执行失败处理机制

TM收到RM返回的中断后会向每个RM发送abort(中断)请求,RM在这个阶段如果收到abort请求或者超时等参加都会中断分支事务的执行;

  • doCommit阶段

3PC_doCommit阶段

最终一致性分布式事务解决方案

强一致性分布式事务解决方案要求参与事务的各个节点的数据时刻都要保持一致,因此通过资源管理器锁定的方式来保证,这样会带来性能上的问题;而最终一致性分布式事务不要求参与事务的各个节点数据要时刻保持一致,通过允许数据有中间态,只要一段时间后,数据能够达到最终一致性即可;

典型方案:

  1. TCC模型
  2. 可靠消息最终一致性模型
  3. 最大努力通知型解决方案

优点:

  1. 性能高
  2. 具备可用性
  3. 适合高并发场景

缺点:

  1. 数据会存在一定时间范围内的不一致
  2. 不适合事务要求比较高的场景

TCC模型

TCC模型本质上是一种应用层实现2PC协议的一种方式,CanCommit阶段在TCC模型中是Try阶段,doCommit阶段在TCC模型中是Commit阶段Cancel阶段;

  • TCC的执行流程
  1. Try阶段
    在这个阶段,不会执行任何业务逻辑,仅对业务进行检查,确保能够进行下一步操作;

  2. Commit阶段
    全局事务管理器开始负责对各个资源管理器下发Commit提交命令

  3. Cancel阶段
    在业务执行异常或者出现错误的情况下,需要回滚事务的操作,执行分支事务的取消操作,并且释放Try阶段预留的资源;

  • TCC模型的优缺点

优点:

  1. TCC是在应用层控制事务,对于事务的控制又更小的粒度
  2. Confim阶段和Cancel阶段的方法具备幂等性,通过重试机制保证分布式事务执行完成后的数据一致性
  3. TCC由于是应用层协议,天然支持横向扩展,避免了XA模型的单点问题

缺点:

  1. TCC嵌入到业务代码中,每个资源服务器的分支事务都需要被拆分成Try\Commit\Cancel等三个方法;
  • TCC需要注意的问题
  1. 空回滚问题
    指的是由于网络或者其他原因导致RM的Try请求为接收到,而接收到Cancel请求,Cancel在未Try的基础上错误的回滚业务数据;
    解决空悬挂问题的关键是在于在执行Cancel请求时需要先判断是否已执行Try请求,常用的方法有通过流水表的形式进行判断;

  2. 悬挂问题
    指的是只进行Try,但是由于超时或者时序问题(try-延迟,cancel,try-到达)在业务数据终态后重新执行try请求了,由于TM未感知到该次Try,因此不会进行释放,常用的解决方案有:Try阶段不锁资源Try阶段通过业务数据判断是否能够进行

可靠消息最终一致性解决方案

可靠消息最终一致性分布式事务解决方案指的是事务的发起方执行完成本地事务之后,发出一条消息,事务的参与方订阅该消息,本质上是通过消息系统完成事务的流转;

事务消息发送分为两个阶段。第一阶段会发送一个半事务消息,半事务消息是指暂不能投递的消息,生产者已经成功地将消息发送到了 Broker,但是Broker 未收到生产者对该消息的二次确认,此时该消息被标记成“暂不能投递”状态,如果发送成功则执行本地事务,并根据本地事务执行成功与否,向 Broker 半事务消息状态(commit或者rollback),半事务消息只有 commit 状态才会真正向下游投递。如果由于网络闪断、生产者应用重启等原因,导致某条事务消息的二次确认丢失,Broker 端会通过扫描发现某条消息长期处于“半事务消息”时,需要主动向消息生产者询问该消息的最终状态(Commit或是Rollback)。这样最终保证了本地事务执行成功,下游就能收到消息,本地事务执行失败,下游就收不到消息。总而保证了上下游数据的一致性。

RocketMQ事务消息的详细交互流程

最大努力通知型解决方案

适用场景:适用于对最终一致性时间敏感度较低的场景,并且事务被动方的处理结果不会影响到事务主动方,典型的适用场景是支付平台异步通知商户支付结果;

这种方案类似于接口交互来实现事务的一致性;

最大努力通知型解决方案需要实现的功能是可查询操作幂等操作

简单来说就是通过幂等重试查询来实现,适用于和三方接口进行交互时使用;

  • 最大努力通知型解决方案和可靠消息最终一致性的区别
  1. 设计不同
    a. 可靠消息最终一致性解决方案是需要事务发起方保证将消息发送成功
    b. 最大努力通知型解决方案只是要求尽最大努力将消息通知给业务被动发起方,不一定保证业务方能够接收到消息;

  2. 业务场景不同
    a. 可靠消息最终一致性解决方案可以看成异步方式达到事务的最终一致性,时效性上更高
    b. 最大努力通知型解决方案不保证达到最终一致性的时效,这取决于事务接收方

  3. 解决的问题不同
    a. 可靠消息最终一致性解决方案是一个遵循同一个事务机制的出发点,有TM\RM等角色;
    b. 最大努力通知型解决方案是按照系统与系统直接完成事务一致性进行出发的;

总结

本文作为了解事务以及分布式事务的基础理论,主要有:

  1. MySQl实现事务的原理:关键字:Redo LogUndo LogBin LogXA事务
  2. Spring的事务管理:关键字:PlatformTransactionManagerTransactionDefinitionTransactionStatus事务的隔离级别事务的传播机制事务的失效场景
  3. 分布式事务的理论基础:关键字:CAPBase理论强一致性的分布式事务解决方案最终一致性分布式事务解决方案2PC3PCTCC可靠消息最终一致性解决方案最大努力通知型解决方案

  TOC