当前位置: 首页 > news >正文

分布式事务一致性:本地消息表设计与实践

概念

本地消息表是一种常见的解决分布式事务问题的方法。其核心思想是将分布式事务拆分成本地事务来处理,通过消息队列来保证各个本地事务的最终一致性。

实现步骤

  • 创建本地消息表:在数据库中创建一个本地消息表,用于存储待发送的消息以及消息的发送状态和相关信息。表结构通常包含字段如 message_id(消息唯一标识)、message_body(消息内容)、status(消息状态,如待发送、已发送等)、create_time(消息创建时间)等;

  • 业务处理与消息记录:在业务逻辑中,当需要发送消息时,首先将消息插入到本地消息表中,设置状态为待发送。然后执行业务逻辑,并将业务变更信息与消息记录插入操作放在同一个本地事务中;

  • 消息发送:创建一个后台线程或定时任务,定时扫描本地消息表中状态为待发送的消息,并将这些消息发送到消息队列。在成功发送到消息队列后,将消息表中对应的状态修改为已发送;

  • 消息消费:消费者监听消息队列,解析消息内容,并执行相应的业务逻辑处理。此步骤必须保证幂等性,即多次消费相同的消息不会导致数据不一致;

  • 消息状态确认:当消息消费完成后,进行状态变更。如果消费失败,需要根据失败原因进行重试或人工处理;

在这里插入图片描述

注意事项

  • 消息的幂等性:消费者必须保证接口的幂等性,以防止消息重复处理导致的数据不一致;
  • 本地消息表的设计:需要考虑到消息状态、重试次数、创建时间等字段,以便实现消息的跟踪和管理;
  • 定时任务和重试机制:实现定时任务或者重试机制来确保消息的可靠发送和处理;

缺点及解决方式

  • 消息堆积、扫表效率慢:可以通过索引优化、分页查询、分库分表、多线程分段查询等方法提高效率;
  • 定时任务扫表延迟问题:可以通过异步发送MQ改为同步调用接口、发送MQ延迟消息、分布式定时任务等方法减少延迟;

应用场景

本地消息表适用于金融、电商等领域,尤其适用于涉及多个服务交互的复杂交易场景,如资金转账、订单创建等。通过其强大功能,可以确保在分布式环境中实现事务的一致性和可靠性,有效防止数据不一致的问题。

通过上述方法,可以在不使用开源框架的情况下,利用本地消息表实现分布式事务,保证数据的一致性和系统的稳定性。

实际使用

下面是一个消息表的设计

CREATE TABLE ` mq_notify ` (` id ` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT '自增主键',` payment_no ` varchar(30) NOT NULL COMMENT '订单号',` message ` varchar(1000) DEFAULT NULL COMMENT 'mq message',` retry ` tinyint(4) NOT NULL COMMENT '发送剩余次数',` status ` tinyint(4) NOT NULL COMMENT '状态',` yn ` tinyint(4) NOT NULL COMMENT '是否有效',` create_time ` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',` update_time ` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '修改时间',PRIMARY KEY (` id `) ,KEY ` idx_status ` (` status `)
) ENGINE = InnoDB COMMENT = 'mq消息表'

在插入消息表时,可以设置重试的最大次数,比如 3。

在定时任务扫描时,筛选retry > 0 且 status = 'init' 的消息记录,发送mq成功,status 更新为'finish',发送mq失败,retry 次数减一。

如果消息发送 3 次还没有成功,此时就需要报警人工介入了。

http://www.lryc.cn/news/442089.html

相关文章:

  • 深入浅出Docker
  • Flink 与 Kubernetes (K8s)、YARN 和 Mesos集成对比
  • Python 集合的魔法:解锁高效数据处理的秘密
  • Go必知必会:构建复杂数据模型的基石
  • 大数据Flink(一百一十七):Flink SQL的窗口操作
  • 【西电电装实习】6. 手装无人机的蓝牙断连debug
  • AIGC实战之如何构建出更好的大模型RAG系统
  • 【数据结构-差分】力扣1589. 所有排列中的最大和
  • Spark部署文档
  • Broadcast:Android中实现组件及进程间通信
  • 5分钟熟练上手ES的具体使用
  • lambda 自调用递归
  • mac中git操作账号的删除
  • AI Agent的20个趋势洞察
  • Spring Boot-定时任务问题
  • 从混乱到清晰!借助Kimi掌握螺旋型论文结构的秘诀!
  • 中国电子学会202306青少年软件编程(Python)等级考试试卷(二级)真题
  • 样本册3D翻页电子版和印刷版同时拥有是一种什么体验
  • 8586 括号匹配检验
  • 案例精选 | 聚铭助力河北省某市公安局筑牢网络安全防护屏障
  • VBS学习2:问题解决(文件中含义中文运行报错或者中文乱码)
  • 首次揭秘行业内幕!范罗士、希喂、有哈、小米、安德迈宠物空气净化器实测分析
  • 1267:【例9.11】01背包问题(信奥一本通)
  • 信息化时代下的高标准农田灌区:变革与机遇并存
  • 【系统架构设计师-2013年真题】案例分析-答案及详解
  • git merge如何忽略部分路径
  • spring boot导入多个配置文件
  • 硬件工程师笔试面试——无线通讯模块
  • 开源PHP免费家谱应用Webtrees简介
  • kafka消息发送几种方式