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

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

概念

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

实现步骤

  • 创建本地消息表:在数据库中创建一个本地消息表,用于存储待发送的消息以及消息的发送状态和相关信息。表结构通常包含字段如 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.kler.cn/news/312334.html

相关文章:

  • Jenkins自动化部署后端项目看这篇就够了
  • ubuntu安装emqx
  • Vue(13)——router-link
  • MATLAB基本语句
  • LLM(大语言模型)和AIGC入门学习路线图,零基础入门到精通,收藏这一篇就够了
  • JVM 调优篇5 jvm性能监控
  • DHCP服务(relay中继)实验简述
  • OpenCV绘制ROI区域(五)
  • constexpr与const的区别
  • 【正负交替的分数求和】
  • Linux环境基础开发工具---vim
  • 4×4矩阵键盘详解(STM32)
  • 什么是 WebApiEngine?
  • C#中单例模式CSingleton
  • 前端如何快速调试线上问题
  • react的组件的概念和使用
  • 家庭聚餐:用白酒传递亲情与温暖
  • 滚雪球学SpringCloud[4.2讲]: Zuul:Netflix API Gateway详解
  • 浅谈vue2.0与vue3.0的区别(整理十六点)
  • npm run build报Cannot find module错误的解决方法
  • 誉龙视音频 Third/TimeSyn 远程命令执行复现
  • weblogic CVE-2020-14882 靶场攻略
  • 【百日算法计划】:每日一题,见证成长(018)
  • pytorch使用技巧
  • Designify——AI优化图像设计,自动去背景、调整构图、添加视觉效果,创建高质量的设计图像
  • 2024 Oracle CloudWorld的信息量实在太大了
  • Pikachu靶场之XSS
  • Leetcode面试经典150题-97.交错字符串
  • 记一次kafka消息丢失问题排查
  • [SDX35+WCN6856]SDX35 + WCN6856 WiFi可以up起来之后无法扫描到SSID