深入理解分布式事务-原理与实践-分布式事务原理
在上一章中已经介绍了分布式事务的基础知识了,这一章将会介绍主要的几种分布式事务的原理,包括XA强一致性分布式事务原理、TCC分布式事务原理、可靠消息型分布式事务原理、最大努力通知型分布式事务原理
XA强一致性分布式事务原理
X/Open组织定于的分布式事务标准规划被称为X/Open DTP模型,定义了事务处理的规划和API,具体的实现由各个厂商进行负责实现;
-
DTP模型
主要定义了3个组件,分别是应用程序、资源管理器、事务管理器
应用程序:定义事务边界
资源管理器:提供访问资源的方式
事务管理器:分配事务ID、监控事务的执行进度、负责事务的提交和回滚 -
xa规范
- xa_start:负责开启或恢复一个分支事务
- xa_end:负责暂停或终止一个分支事务
- xa_prepare:负责对一个分支事务进行预提交操作
- xa_commit:负责提交一个分支事务
- xa_rollback:负责回滚一个分支事务
- xa_recover:负责在系统崩溃后,恢复未完成的分支事务
- xa事务的缺陷
- 同步阻塞
MySQl需要配合串行化的事务隔离级别来使用XA事务,这会导致性能下降。 - 单点故障
XA事务的协调者是事务管理器,如果事务管理器出现故障,资源管理器会一直等待,不会主动释放资源; - 数据不一致
在二阶段过程中,如果协调者向一部分资源管理器发送了提交请求,而另一部分资源管理器由于故障未能收到提交请求,就会导致数据不一致。
TCC分布式事务原理
TCC分布式事务最核心的思想就是在应用层将一个完整的事务拆分成三个阶段: Try、Confirm、Cancel。在某种程度上讲,TCC是一种资源,实现了Try-Confirm-Cancel三个操作接口,本质上还是两阶段提交的变种。
TCC分布式事务属于最终一致性下的补偿性事务
使用TCC时需要注意:
- 幂等性
Confirm 和 Cancel 阶段可能会因为网络超时等原因被重试。因此,这两个方法必须是幂等的,即无论被调用多少次,结果都必须一致。开发者需要自行实现幂等性检查,例如通过一个唯一的事务 ID。 - 空回滚(Empty Rollback)
如果一个服务的 Try 阶段因为网络问题失败了,但 Cancel 阶段的请求却成功到达了,那么就会发生“空回滚”。Cancel 方法被调用时,Try 方法实际上没有执行,Cancel 必须能够识别这种情况并安全地退出,不执行任何回滚操作。
为每一个全局事务生成一个唯一的事务ID,并在 Try 阶段执行时,将这个事务ID和一些状态信息记录下来。在 Cancel 阶段执行时,首先检查这个唯一的事务ID对应的记录是否存在。
如果记录存在:说明 Try 阶段已经成功执行过,此时可以安全地执行 Cancel 逻辑。
如果记录不存在:说明 Try 阶段没有成功执行(可能是因为网络延迟或请求失败),此时可以判断为空回滚,Cancel 方法应该直接返回,不执行任何业务回滚操作。
简单来说,就是通过一个事务日志或状态记录来判断 Try 阶段是否成功执行,避免 Cancel 方法在不恰当的时机被调用。
- 防悬挂
悬挂问题的本质是:Try 阶段的资源被锁定后,Confirm 或 Cancel 阶段的请求永远没有到达,导致资源一直被占用。
设置一个超时时间,来自动清理那些长时间没有得到 Confirm 或 Cancel 最终指令的 Try 事务。
可靠消息最终一致性分布式事务原理
可靠消息最终一致性分布式事务是一种依赖消息中间件完成资源管理器之间相互协作的最终一致性解决方案;
基本流程如下:
- 业务服务 A 在执行某个操作时,首先将操作消息发送到消息队列中,并立即返回成功响应。
- 消息队列将消息异步投递到业务服务 B,业务服务 B 接收到消息后执行相应的操作。
- 业务服务 B 在处理完消息后,将处理结果(成功或失败)发送回消息队列。
- 消息队列根据处理结果,通知业务服务 A 进行相应的补偿操作。
这种方式的优点在于:
- 解耦:业务服务 A 和 B 之间通过消息队列进行通信,降低了耦合度。
- 异步:业务服务 A 不需要等待业务服务 B 的处理结果,可以提高系统的吞吐量。
- 最终一致性:通过消息的可靠投递和补偿机制,可以保证系统的最终一致性。
在实现可靠消息最终一致性分布式事务时,需要注意以下几点:
- 消息的可靠投递:确保消息能够被可靠地投递到消息队列中,并且能够被业务服务 B 正确处理。
- 消息的幂等性:业务服务 B 在处理消息时,需要确保操作的幂等性,以避免重复处理导致的数据不一致。
- 补偿机制:在业务服务 B 处理失败时,需要能够及时触发补偿操作,以保证系统的最终一致性。