本地消息表实现分布式事务

一、基本概念

本地消息表(Local Message Table)是一种基于消息队列+事务日志的分布式事务解决方案,通过将分布式事务拆分为多个本地事务,利用本地事务的ACID特性保证最终一致性。

角色:

  • 事务主动方(消息的发送方)

  • 事务被动方(消息的消费者)


二、核心设计思想

  • 事务拆分:将分布式事务拆分为多个本地事务

  • 消息持久化:在业务事务中同步记录消息到本地数据库

  • 异步通知:通过定时任务或消息队列通知其他服务

  • 重试机制:确保消息最终被消费


三、架构组成


四、工作原理


正常流程

1、事务发起方:

  • 开启本地事务

  • 更新业务数据

  • 插入消息表记录(同事务)

  • 提交事务


2、消息发送:

  • 定时任务扫描消息表

  • 发送未处理的消息到MQ

  • 更新消息状态为"已发送"


3、消息消费:

  • 消费者接收消息

  • 处理业务逻辑

  • 返回ACK确认


异常处理流程

1、消息发送失败:

  • 保持消息状态为"待发送"

  • 下次扫描会重新尝试


2、消费处理失败:

  • 不返回ACK(或返回NACK)

  • 消息队列重新投递

  • 达到重试上限后进入死信队列


整体的流程如下图:

1、写入业务操作和消息记录:

2、在同一个事务中,执行业务操作,并将消息写入消息表中,消息表记录至少包含消息ID、消息内容、目标系统和状态等。

3、事务提交后,业务操作和消息记录都会被持久化到数据库。

4、发送消息和更新消息状态:

5、发送消息到MQ(消息队列)系统。

6、发送成功后,更新消息表状态为已发送。

7、补偿任务处理:

8、消息记录被写入消息表后,补偿任务会定期扫描消息表,寻找尚未被处理的消息,重新发送消息到MQ(消息队列)系统。

9、消费端幂等处理:

10、消费者收到消息之后,需要确保操作具有幂等性,因为消息可能会被重复处理。


五、优点

1、实现简单,只使用一张消息表来维护消息的发送状态。

2、容错性较高,如果消息发送失败,可以使用补偿任务重新发送。

3、实现了分布式系统中数据的最终一致性。


六、优点

数据一致性延迟较高,由于依赖异步消息传递,不能立即保证数据一致性,只能实现最终一致性


七、代码示例


1、消息表设计示例


2、消息生产端


3、消息扫描发送


4、消息消费端

posted @ 2025-04-19 00:59  jock_javaEE  阅读(933)  评论(0)    收藏  举报