分布式事物-本地消息表
什么是本地消息表
本地消息表的方案最初是由 eBay 提出,核心思路是将分布式事务拆分成本地事务进行处理。
方案通过在事务主动发起方额外新建事务消息表,事务发起方处理业务和记录事务消息在本地事务中完成,轮询事务消息表的数据发送事务消息,事务被动方基于消息中间件消费事务消息表中的事务。
这样设计可以避免”业务处理成功 + 事务消息发送失败",或"业务处理失败 + 事务消息发送成功"的棘手情况出现,保证 2 个系统事务的数据一致性。
消息表是一种本地持久化的机制,通过将分布式事务中所涉及到的各种操作记录进消息表中并进行管理,来确保分布式事务的正确性。消息表通常包含如下两个主要部分:消息日志和消息状态。
消息日志用于记录所有有关操作的信息,包括操作类型、操作数据、事务ID、操作状态等。消息状态则用于记录操作执行的状态,包括成功、失败、中断等。通过持久化记录操作信息和操作状态,消息表可以确保当分布式事务重新启动时,所有的操作都能够得到恰当的处理。
使用分布式事务的应用系统可以通过查看与分布式事务相关的消息表记录来监视事务处理的进展情况,以及找到任何可能的故障点并进行修复。
总之,消息表是一种本地化的、可靠的机制,可用于确保分布式事务的正确性。它适用于多个节点同时执行的环境中,可以减少节点间的通信量和协调成本,并显著提升系统的性能和可靠性。
本地消息表处理流程
以电商用户注册为例
1.创建用户(用户服务)
2.用户赠送新人优惠券(支付服务)
用户服务
1.开启事物
2.创建用户相关的业务数据 落库
3.生成一条赠送优惠券的业务消息(状态发送中)
4.提交事物
5.发送消息(也可以依赖mq 直接调用赠送优惠券的服务)
6.如果发送成功则将消息数据改为发送成功
有可能发送消息失败
1.新增一个定时任务扫描发送中的事物 进行补偿(所以消息接收方要做幂等)
优点
- 从应用设计开发的角度实现了消息数据的可靠性,消息数据的可靠性不依赖于消息中间件,弱化了对 MQ 中间件特性(事物特性)的依赖。
- 方案轻量,容易实现。保证最终一致
方案
Spring Cloud:Spring Cloud提供了一些基础设施来协调分布式应用程序,如服务发现、配置管理、熔断器、路由、分布式追踪等。而在分布式事务管理这一块,可以使用Spring Cloud Tencent的Seata来实现消息表。
Atomikos:Atomikos提供了一个可嵌入的、独立的Java事务管理系统(JTA),旨在为Java应用程序提供跨多个数据库、消息队列等资源的ACID事务管理的支持。
Narayana: 是JBOSS应用服务器中的一个JTA实现,采用了B+A+M(补偿+补偿事务管理器+消息机制)架构。其中的补偿事务管理器就是基于消息表的解决方案。
缺点
1) 本地消息表与业务耦合在一起,难于做成通用性,不可独立伸缩。
2)本地消息表是基于数据库来做的,而数据库是要读写磁盘IO的,因此在高并发下是有性能瓶颈的