MQ本地消息事务表

news2024/11/13 8:02:25

纯技术方案水文特此记录

MQ本地消息事务表解决了什么问题?

MQ本地事务表方案解决了本地事务与消息发送的原子性问题,即:事务发起方在本地事务执行成功后消息必须发出去,否则就丢弃消息。实现本地事务和消息发送的原子性,要么都成功,要么都失败。 简而言之就是保证了生产者发送消息的可靠性

实现流程

整体实现思路并不复杂,代码看起来绕,其实就是新增了一张本地消息表,记录消息发送失败的日志,且随当前业务事务一块提交。等到业务事务执行完毕后,在执行发送MQ逻辑,此时如果MQ发送失败了也不打紧,本地表兜着底呢,后面可以通过定时扫表的方式进行MQ消息的重新发送

从代码实现上来看用到了一些小众的 API ,前提知识储备:事务相关组件 TransactionSynchronizationManager 。通过 TransactionSynchronizationManager 我们可以拿到当前线程是否是事务线程,毕竟事务和线程挂钩。我们还可以通过 TransactionSynchronizationManager 为当前事务线程注册一些事件,例如 afterCommit 事件。当事务执行后触发我们的 afterCommit 事件进行真正的 MQ 消息的发送。

手把手带你debug流程

发来一个请求执行事务方法,事务方法里面处理好业务逻辑后,进行MQ可靠消息发送
在这里插入图片描述
由于可靠MQ消息发送被我们的自定义注解做过 @Around 切面处理,因此先走切面逻辑
在这里插入图片描述
来到切面后,由于此时的所有逻辑还在事务里面,因此并不会触发 joinPoint.proceed() 方法《此方法调用会触发 rocketMQTemplate.send(topic, build) 的执行》。开始调用 secureInvokeService.invoke(record, async) 进行MQ消息发送日志入库到本地表。
在这里插入图片描述
入库完了之后呢?开始注册一个 afterCommit 事件,注意这里仅仅是注册事件,并没有触发执行
在这里插入图片描述
注册完成后直接 return null 。其实这个切面针对事务线程就是一个空壳方法,作用仅仅是保存了一条本地MQ消息发送日志而已
在这里插入图片描述
到这一步已经完成了,本地事务与本地MQ消息表的数据原子性了,此时如果如下代码出现业务逻辑异常,不会触发MQ消息发送逻辑。是正常的,如果MQ本地表入库失败的话,业务逻辑会进行回滚。

@Transactional
public void sendSecureMsg(String testRocketMQ, String message, String ccc) {
    log.info("执行其他的业务逻辑");
    mqProducer.sendSecureMsg(testRocketMQ, message, ccc);
}

等待 sendSecureMsg 方法执行完成我们的自定义切面后,事务切面最终会进行事务的 commit 操作。commit 完成后调用之前注册过的 afterCommit 事件,具体事务源码可以看我主页的这篇文章:
全面解读spring注解事务失效场景,伪代码+图文深度解析spring源码运行过程
在这里插入图片描述
当事务提交后开始发送MQ消息

在这里插入图片描述
最终发MQ。发送失败重试几次,重试还是发送失败改本地MQ表的数据状态等待,定时任务扫描重新发即可。

在这里插入图片描述

通过 method.invoke(bean, args); 触发事务方法,事务会失效,即使此方法被自定义切面加强,由于切面中有判断如果当前线程不在事务内,执行的是方法本身的逻辑,因此走的是如下图圈红的地方
在这里插入图片描述
最终调用如下代码发送MQ

    @SecureInvoke
    public void sendSecureMsg(String topic, Object body, Object key) {
        Message<Object> build = MessageBuilder
                .withPayload(body)
                .setHeader("KEYS", key)
                .build();
        else rocketMQTemplate.send(topic, build);
    }

本文总结

这个方案就是新增了一张本地消息表,记录消息发送失败的日志,且随当前业务事务一块提交。等到业务事务执行完毕后,在执行发送MQ逻辑,此时如果MQ发送失败了也不打紧,本地表兜着底呢,后面可以通过定时扫表的方式进行MQ消息的重新发送

如果还不懂这套方案童鞋可以先去搞懂一下,再来阅读本文效果更佳

  1. 事务方法失效场景。即必须通过代理对象进行的方法调用事务才会生效。
  2. 声明式事务整个的代理对象是如何创建、事务运行的整套流程

全面解读spring注解事务失效场景,伪代码+图文深度解析spring源码运行过程

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1703729.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

系统安全扫描扫出了:可能存在 CSRF 攻击怎么办

公司的H5在软件安全测试中被检查出可能存在 CSRF 攻击&#xff0c;网上找了一堆解决方法&#xff0c;最后用这种方式解决了。 1、问题描述 CSRF 是 Cross Site Request Forgery的缩写(也缩写为也就是在用户会话下对某个 CGI 做一些 GET/POST 的事&#xff0c;RIVTSTCNNARGO一这…

香橙派AIpro初体验,详解如何安装Home Assistant Supervised

香橙派AIpro&#xff08;OrangePi AIpro&#xff09;开发版&#xff0c;定位是一块AI开发板&#xff0c;搭载的是华为昇腾310&#xff08;Ascend310&#xff09;处理器。 没想到&#xff0c;这几年的发展&#xff0c;AI开发板也逐渐铺开&#xff0c;记得之前看到华为发布昇腾3…

挑战你的数据结构技能:复习题来袭【3】

chap3 练习1 一. 单选题 1. (单选题)栈和队列具有相同的&#xff08;&#xff09; A. 抽象数据类型B. 逻辑结构C. 存储结构D. 运算 答案: B:逻辑结构 答案分析&#xff1a;逻辑结构都属于线性结构,只是它们对数据的运算不同。 2. (单选题)栈是() A. 顺序存储的线性结构B…

深入理解python列表与字典:数据结构的选择与性能差异

新书上架~&#x1f447;全国包邮奥~ python实用小工具开发教程http://pythontoolsteach.com/3 欢迎关注我&#x1f446;&#xff0c;收藏下次不迷路┗|&#xff40;O′|┛ 嗷~~ 目录 一、列表与字典&#xff1a;基础数据结构的对比 二、列表&#xff1a;逐个遍历的查找方式 …

SARscape5.7已经支持3米陆探一号(LT-1)数据处理

SARsacpe5.6.2.1版本已经开始支持LT-1的数据处理&#xff0c;由于当时只获取了12米的条带模式2&#xff08;STRIP2&#xff09;例子数据&#xff0c;对3米条带模式1&#xff08;STRIP1&#xff09;数据的InSAR处理轨道误差挺大&#xff0c;可能会造成干涉图异常。 SARsacpe5.7最…

Android Display Graphics #1 整体框架介绍一

软件基础 Android的framework层提供了一系列的图像渲染API&#xff0c;可绘制2D和3D。简单理解就是上层开发APP的小伙伴提供了接口&#xff0c;开发者可以直接显示对应的自己内容。但如果掌握了Display底层逻辑再写上层app&#xff0c;会有掌控力&#xff0c;出问题可以根据lo…

vs code怎么补全路径,怎么快捷输入文件路径

安装插件&#xff1a; 链接&#xff1a;https://marketplace.visualstudio.com/items?itemNamejakob101.RelativePath 使用 按住 Ctrl Shift H&#xff0c;弹出窗口&#xff0c;输入文件补全&#xff0c;回车就可以了 排除文件 如果你的项目下文件太多&#xff0c;它会…

2000-2017年各省经济政策不确定性指数

2000-2017年各省经济政策不确定性指数 1、时间&#xff1a;2000-2017年 2、来源&#xff1a;国际能源转型学会 3、范围&#xff1a;31省 4、构建说明&#xff1a; 按照Baker等&#xff08;2016&#xff09;的方法&#xff0c;在中国省级范围内构建了经济政策不确定性&…

如果任务过多,队列积压怎么处理?

如果任务过多,队列积压怎么处理? 1、内存队列满了应该怎么办2、问题要治本——发短信导致吞吐量降低的问题不能忽略!!3、多路复用IO模型的核心组件简介1、内存队列满了应该怎么办 如图: 大家可以看到,虽然现在发短信和广告投递,彼此之间的执行效率不受彼此影响,但是请…

快速版-JS基础01书写位置

1.书写位置 2.标识符 3.变量 var&#xff1a;声明变量。 &#xff08;1&#xff09;.变量的重新赋值 &#xff08;2&#xff09;.变量的提升 打印结果&#xff1a;console.log(变量名) 第一个是你写在里面的。 第二个是实际运行的先后之分&#xff0c;变量名字在最前面。变量…

sql注入less8——布尔盲注

sql注入第八关卡是布尔盲注&#xff0c;我们将看不到一般的返回值&#xff0c;只能通过You are in......的消失与否来判断自己输入的字符是否与查询的数据的字符相同&#xff0c;相同则显示You are in......&#xff0c;相反则不显示&#xff0c;如下图所示&#xff1a; 查询语…

每天五分钟深度学习框架pytorch:tensor张量的维度转换大全

本文重点 在深度学习中比较让人头疼的一点就是矩阵的维度,我们必须构建出符合神经网络维度的矩阵,只有将符合要求的矩阵放到神经网络中才可以运行神经网络,本节课程我们将学习以下tensor中维度的变化。 view和shape View和shape,这两个方法可以完成维度的变换操作,而且使…

YOLOv10来了

B站&#xff1a;啥都会一点的研究生公众号&#xff1a;啥都会一点的研究生 前言 YOLOv10 由清华大学研究人员在 Ultralytics版基础上进行进一步开发&#xff0c;引入了一种新的实时目标检测方法&#xff0c;解决了以前版本 YOLO 在后处理和模型架构方面的不足。通过消除非最大…

【WEB前端2024】开源智体世界:乔布斯3D纪念馆-第30课-门的移动动画

【WEB前端2024】开源智体世界&#xff1a;乔布斯3D纪念馆-第30课-门的移动动画 使用dtns.network德塔世界&#xff08;开源的智体世界引擎&#xff09;&#xff0c;策划和设计《乔布斯超大型的开源3D纪念馆》的系列教程。dtns.network是一款主要由JavaScript编写的智体世界引擎…

mysql中连接查询的成本

大家好。上篇文章我们讲了mysql中成本的含义以及单表查询如何计算成本。现在我们接着讲讲mysql中连接查询的成本。 在讲之前&#xff0c;我们先创建两张一样的表single_table和single_table2&#xff0c;并在表中插入10000条数据。在下面的讲解中&#xff0c;我们称single_tab…

Ubuntu22.04之解决:忘记登录密码(二百三十二)

简介&#xff1a; CSDN博客专家&#xff0c;专注Android/Linux系统&#xff0c;分享多mic语音方案、音视频、编解码等技术&#xff0c;与大家一起成长&#xff01; 优质专栏&#xff1a;Audio工程师进阶系列【原创干货持续更新中……】&#x1f680; 优质专栏&#xff1a;多媒…

OpenHarmony 实战开发——ArkUI中的线程和看门狗机制

一、前言 本文主要分析ArkUI中涉及的线程和看门狗机制。 二、ArkUI中的线程 应用Ability首次创建界面的流程大致如下&#xff1a; 说明&#xff1a; • AceContainer是一个容器类&#xff0c;由前端、任务执行器、资源管理器、渲染管线、视图等聚合而成&#xff0c;提供了生…

Transformers集成SwanLab实现AI训练可视化监控

&#x1f917;HuggingFace Transformers Hugging Face 的 Transformers 是一个非常流行的开源库&#xff0c;它提供了大量预训练的模型&#xff0c;主要用于自然语言处理&#xff08;NLP&#xff09;任务。这个库的目标是使最新的模型能够易于使用&#xff0c;并支持多种框架&…

Android低代码开发 - MenuPanel的源码剖析和基本使用

看了我上篇文章Android低代码开发 - 像启蒙和乐高玩具一样的MenuPanel 之后&#xff0c;本篇开始讲解代码。 源代码剖析 首先从MenuPanelItemRoot讲起。 package dora.widget.panelinterface MenuPanelItemRoot {/*** 菜单的标题。** return*/var title: String?fun hasTit…

第16篇:JTAG UART IP应用<三>

Q&#xff1a;如何通过HAL API函数库访问JTAG UART&#xff1f; A&#xff1a;Quartus硬件工程以及Platform Designer系统也和第一个Nios II工程--Hello_World的Quartus硬件工程一样。 Nios II软件工程对应的C程序调用HAL API函数&#xff0c;如open用于打开和创建文件&#…