记MySQL事务+消息队列引起的问题

问题描述:

先说一下流程:后端保存前端提交的图表信息,然后发送异步消息到消息队列,由下游服务去处理图表信息。

部署项目到服务器,验证项目功能的时候,出现了以下错误:数据库存在数据。下游服务查不到数据库的数据

// service代码
@Override
@Retryable
@Transactional
public ChartVo genChartByAiAsyncMq(Long uid, MultipartFile multipartFile, GenChartByAiRequest genChartByAiRequest) {// ...省略Chart chart = Chart.builder().name(name).goal(goal).chartData(data).chartType(chartType).uid(uid).status("wait").build();boolean save = this.save(chart);if(!save){log.info("保存表单失败");throw new RuntimeException("保存表单失败");}List<Chart> list = this.list();log.info("chart长度:{}", list.size());// 发送消息,触发异步处理biMessageProducer.sendMessage(String.valueOf(chart.getId()));log.info("发送消息成功");// 省略
}

下游服务处理代码

@SneakyThrows
@RabbitListener(queues = {MQConstants.BI_QUEUE_NAME}, ackMode = "MANUAL")
public void receiveMessage(String message, Channel channel, @Header(AmqpHeaders.DELIVERY_TAG) long deliveryTag){log.info("receive message: {}", message);// 检查消息是否为空if(StringUtils.isBlank(message)){log.info("消息不能为空");channel.basicNack(deliveryTag, false, false);throw new RuntimeException("消息不能为空");}List<Chart> list = biService.list();log.info("图表列表长度:{}", list.size());// 尝试将消息解析为图表ID,并查询图表信息Long chartId = Long.parseLong(message);Chart chart = biService.getById(chartId);log.info("图表信息:{}", chart);// 图表不存在时的处理if(chart == null){log.info("图表不存在");channel.basicNack(deliveryTag, false, false);throw new RuntimeException("图表不存在");}// 省略
}

日志输出如下:
在这里插入图片描述
数据库信息:
在这里插入图片描述

解决过程

首先说明一下,这个错误之前没有出现过,下午出错,再次测试的时候,也会出现正常的情况,只不过错误占比有点高(10次有6次获取不到数据库消息)。

分析的过程:

步骤1、首先在上游服务和下游服务打印日志,查看数据库有多少条数据,上游服务显示有2条数据,下游服务显示有1条数据
在这里插入图片描述

步骤2、找错的时候,看见方法加了事务注解@Transactional,这个时候想到可能是事务影响(后面分析原因),然后取掉注解,重新验证,发现没有出错
在这里插入图片描述

原因分析

为什么会出现这个错误呢?

我觉得是由MySQL的事务和网络引起的,

MySQL事务+网络

我们都知道MySQL(8.x版本)的事务的隔离级别默认是可重复读(RR),那么一个事务在操作完成之前,对其他事务是不看见的,所以就说,方法中先保存图表信息到数据库,然后发送消息到消息队列,再执行方法的后续过程。发送消息到队列之后,可能数据库事务还没有提交,但是消息发送成功了,就立刻被消费者端消费,此时,消费者端查询数据库中的图表信息,当然查不到,因为生产者端的事务还没有提交。

之前没有出错,这次验证出错分析

服务端将消息发送消息队列,由于网络有延迟,导致事务提交之后,消息才被消费端消费。

解决方法

1、手动提交事务,不使用注解
2、设置延迟队列,但是这个延迟的时间具体是多少,我们无法确定,所以最后采用第一种方法解决此问题。

@Slf4j
@Service
public class BiServiceImpl extends ServiceImpl<ChartMapper, Chart> implements BiService {@Resourceprivate PlatformTransactionManager transactionManager;@Override@Retryablepublic ChartVo genChartByAiAsyncMq(Long uid, MultipartFile multipartFile, GenChartByAiRequest genChartByAiRequest) {TransactionStatus transactionStatus = transactionManager.getTransaction(new DefaultTransactionDefinition());try{// 省略...Chart chart = Chart.builder().name(name).goal(goal).chartData(data).chartType(chartType).uid(uid).status("wait").build();boolean save = this.save(chart);if(!save){log.info("保存表单失败");throw new RuntimeException("保存表单失败");}transactionManager.commit(transactionStatus);List<Chart> list = this.list();log.info("chart长度:{}", list.size());// 发送消息,触发异步处理biMessageProducer.sendMessage(String.valueOf(chart.getId()));log.info("发送消息成功");// 省略...}catch (Exception e){log.error("AI 异步调用失败", e);transactionManager.rollback(transactionStatus);throw new RuntimeException("AI 异步调用失败");}}
}

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

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

相关文章

C++ 音视频传输

目录 一、概述 二、音视频采集 1、视频采集 2、音频采集 三、音视频编码 四、网络传输 五、音视频解码 六、音视频播放 1、视频播放 2、音频播放 七、音视频同步 1. 时间戳管理 2. 缓冲控制 3. 同步策略 3.1 视频为主 3.2 音频为主 3.3 同步点策略 3.4 缓冲区…

Spring Boot+vue社区养老系统(智慧养老平台)

使用技术&#xff1a; springbootvueMySQL 主要功能&#xff1a; 管理员 登录个人资料密码管理, 用户管理:床位类型管理,床位管理,护工管理,老人管理 咨询登记管理&#xff0c;预约登记管理,老人健康信 息管理,费用管理等功能.护工角色包含以下功能: 护工登录&#xff0c;个…

Elastaticsearch与SpringBoot集成的互联网的实战分享

以前有过类似的文章&#xff0c;今天升级版分享重磅内容&#xff0c;Elastaticsearch与SpringBoot集成的互联网的实战。 一、需求分析&#xff1a; 起因是这样的&#xff0c;产品有这样一个需求&#xff1a;数据中的标题、内容、关键词等实现结构化搜索和半结构化搜索、数据时…

自2008年金融危机以来首次,欧洲AAA级CMBS投资者面临亏损

在欧洲预期损失之前&#xff0c;美国AAA级CMBS投资者已经遭受了打击。即便是最高信用等级的投资也不再安全&#xff0c;全球金融系统可能存在一些严重的问题。 历史罕见&#xff0c;最安全的AAA级债权人&#xff0c;在没有发生经济危机的情况下&#xff0c;出现了损失&#xff…

外排序(C语言实现)

前言 本篇博客讲解一下外排序&#xff0c;看这篇排序你的先去看一下&#xff1a;八大经典排序算法-CSDN博客 &#x1f493; 个人主页&#xff1a;普通young man-CSDN博客 ⏩ 文章专栏&#xff1a;排序_普通young man的博客-CSDN博客 若有问题 评论区见&#x1f4dd; &#x1f3…

【数据结构】带头双向循环链表的实现及链表顺序表的区别

目录 一、带头双向循环链表接口实现 连接关系&#xff1a; 创建哨兵位&#xff08;表头&#xff09;&#xff1a; 头插——头删&#xff1a; 尾插——尾删&#xff1a; 查找——打印&#xff1a; 指定位置pos前插入&#xff0c;删除pos位置&#xff1a; 链表销毁&#x…

真实能够生产光刻机地方

目前全球制造光刻机的主要国家包括&#xff1a; 1. **荷兰**&#xff1a;ASML&#xff08;阿斯麦&#xff09;公司是全球最大的光刻机制造商&#xff0c;总部设在荷兰。ASML公司的光刻机被广泛应用于半导体行业&#xff0c;是制造高性能芯片的关键设备之一。 2. **日本**&…

setInterval 定时任务执行时间不准验证

一般在处理定时任务的时候都使用setInterval间隔定时调用任务。 setInterval(() > {console.log("interval"); }, 2 * 1000);我们定义的是两秒执行一次&#xff0c;但是浏览器实际执行的间隔时间只多不少。这是由于浏览器执行 JS 是单线程模式&#xff0c;使用se…

解决ArcGIS导出的svg格式的图片插入Word后的字体问题

背景 在ArcGIS中设置字体为Times New Roman&#xff0c;但导入Word后字体转为等线。 ArcGIS中的Layout 导入Word​​​​​​ 原因分析 Word无法识别嵌入进SVG格式文件中的字体。 解决方案 在Export Layer窗口中&#xff0c;将Embed fonts取消勾选&#xff0c;Convert cha…

【深度学习】 探讨Stable Diffusion模型的训练及其偏向性

探讨Stable Diffusion模型的训练及其偏向性 近年来&#xff0c;生成式模型在图像生成领域取得了显著进展&#xff0c;特别是Stable Diffusion模型。作为一种基于扩散过程的生成模型&#xff0c;Stable Diffusion模型展现了生成高质量图像的巨大潜力。然而&#xff0c;与所有机…

Makefile的链接器错误:最不易被发现的bug

makefile编译时出现 collect2: error: ld returned 1 exit status我的makefile的语句为&#xff1a; # 定义编译器 CXX g# 定义编译器标志 CXXFLAGS -v -g -Wall -Wno-write-strings -stdc11# 定义Oracle的库和包含路径 ORAINCL -I/oracle/home/rdbms/public ORALIB -L/o…

本地离线模型搭建指南-RAG架构实现

搭建一个本地中文大语言模型&#xff08;LLM&#xff09;涉及多个关键步骤&#xff0c;从选择模型底座&#xff0c;到运行机器和框架&#xff0c;再到具体的架构实现和训练方式。以下是一个详细的指南&#xff0c;帮助你从零开始构建和运行一个中文大语言模型。 本地离线模型搭…

基于SSM+Vue+微信小程序的大学生就业平台系统+毕业论文

项目包含前台和后台两部分&#xff1a;多角色登录&#xff0c;功能完善&#xff0c;界面优美 前台主要功能实现&#xff1a;首页列表查看、求职信息管理、简历管理、面试邀请管理、个人中心等 后台主要功能实现&#xff1a;首页、个人中心、学生管理、企业管理、企业类型管理…

【Android面试八股文】你来讲一讲View`滑动操作可以通过哪些方式来实现?

文章目录 1. 通过`scrollTo()`和`scrollBy()``scrollTo(int x, int y)``scrollBy(int dx, int dy)``scrollTo()` 和 `scrollBy()` 的区别2. 使用动画2.1 属性动画(`ObjectAnimator`)2.2 视图动画(`TranslateAnimation`)两者的区别选择哪种动画?3. 使用Scroll实现平滑滚动效…

浏览器插件利器-allWebPluginV2.0.0.14-bata版发布

allWebPlugin简介 allWebPlugin中间件是一款为用户提供安全、可靠、便捷的浏览器插件服务的中间件产品&#xff0c;致力于将浏览器插件重新应用到所有浏览器。它将现有ActiveX插件直接嵌入浏览器&#xff0c;实现插件加载、界面显示、接口调用、事件回调等。支持谷歌、火狐等浏…

Maven和JAVA_HOME的关系

在Java开发中&#xff0c;Maven和JAVA_HOME是两个关键的概念&#xff0c;它们在构建和运行Java应用程序时具有不同的角色&#xff0c;但却相互关联。以下是它们的关系和各自的作用&#xff1a; JAVA_HOME 定义和作用: JAVA_HOME是一个环境变量&#xff0c;它指向JDK&#xff0…

【C++】初始化列表、匿名对象、static成员、友元、内部类

文章目录 一、初始化列表构造函数体赋值初始化列表explicit关键字 二、匿名对象三、static成员四、友元友元函数友元类 五、内部类六、练习题 一、初始化列表 构造函数体赋值 实际上&#xff0c;构造函数的函数体内&#xff0c;并不是对 对象 初始化的地方&#xff0c;而是对…

34、shell数组+正则表达式命令

0、课前补充 jiafa () { result$(echo " $1 $2 " | bc ) print "%.2f\n" "$result" } ##保留小数点两位 薄弱加强点 a$(df -h | awk NR>1 {print $5} | tr -d %) echo "$a"一、数组 1.1、定义 数组的定义&am…

dockercompose

安装dockerconpose #上传docker-compose安装包 chmod x docker-compose mv docker-compose /usr/bin/ [rootlocalhost ~]# docker-compose --version docker-compose version 1.24.1, build 4667896b文件格式以及编写注意事项 YAML 是一种标记语言&#xff0c;它可以很直观的…

数据分析BI仪表盘搭建

BI仪表盘搭建六个原则&#xff1a; 1.仪表盘搭建符合业务的阅读&#xff0c;思考和操作逻辑。 2.明确仪表盘主题&#xff0c;你的用户对什么感兴趣。 普通业务人员&#xff1a;销售&#xff1a;注册&#xff0c;激活&#xff0c;成交投放&#xff1a;消耗&#xff0c;转化率…