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

消息队列导致数据库数据读取不一致解决方案

我使用的是在数据库添加一个版本字段,记录版本,保证版本一致性,就能保证每次读取的是需要的内容。

具体问题:使用消息队列时,发送方给接收方发送消息,接收方修改了数据库的同时发送方查询数据库,由于是异步操作,会导致发送方读取的数据是修改前的数据,导致数据不一致的问题。

代码:

发送方

// 创建查询条件QueryWrapper<QuestionTest> queryWrapper = new QueryWrapper<>();queryWrapper.eq("userId", loginUser.getId()).eq("questionId", questionId);
// 查询是否存在记录QuestionTest existingRecord = questionTestMapper.selectOne(queryWrapper);插入一条新记录existingRecord.setQuestionId(questionId);existingRecord.setUserId(loginUser.getId());if (existingRecord.getId() == null) {existingRecord.setVersion(Long.valueOf(0));questionTestMapper.insert(existingRecord);}Long id = existingRecord.getId(); // 获取新插入记录的idLong version = existingRecord.getVersion();existingRecord.setVersion(version);Map<String, Object> taskMessage = new HashMap<>();taskMessage.put("id", id);taskMessage.put("questionId", questionId);taskMessage.put("userId", loginUser.getId());taskMessage.put("codeLanguage", questionSubmitAddRequest.getCodeLanguage());taskMessage.put("userCode", questionSubmitAddRequest.getUserCode());taskMessage.put("input", questionSubmitAddRequest.getUserJudgeCase().getInput());taskMessage.put("answer", question.getAnswer());taskMessage.put("version", version);
//        System.out.println(taskMessage);String message = JSONUtil.toJsonStr(taskMessage);
//        System.out.println(message);myMessageProducer.sendMessage("code_exchange", "my_routingKey_test", message);// 等待接收方处理完毕
//        Long newVersion = null;while (!existingRecord.getVersion().equals(version + 1)) {existingRecord = questionTestMapper.selectById(id);}return existingRecord;

 接收方:

Map<String, Object> taskMessage = JSONUtil.toBean(message, Map.class);Long questionId = Long.valueOf(taskMessage.get("questionId") != null ? String.valueOf(taskMessage.get("questionId")) : "0");Long id = Long.valueOf(taskMessage.get("id") != null ? String.valueOf(taskMessage.get("id")) : "0");Long userId = Long.valueOf(taskMessage.get("userId") != null ? String.valueOf(taskMessage.get("userId")) : "0");String codeLanguage = String.valueOf(taskMessage.get("codeLanguage"));String userCode = String.valueOf(taskMessage.get("userCode"));String input = String.valueOf(taskMessage.get("input"));String answer = String.valueOf(taskMessage.get("answer"));Long version = Long.valueOf(taskMessage.get("version") != null ? String.valueOf(taskMessage.get("version")) : "0");
//            System.out.println(answer);// 使用正确代码生成预期结果String output = judgeService.dojudgeTestCode(answer, input, codeLanguage);// 使用用户代码生成实际结果String predicted = judgeService.dojudgeTestCode(userCode, input, codeLanguage);JudgeCase currentJudgeCase = new JudgeCase();currentJudgeCase.setInput(input);currentJudgeCase.setOutput(output);JudgeCase userJudgeCase = new JudgeCase();userJudgeCase.setInput(input);userJudgeCase.setOutput(predicted);log.info("测试任务处理成功,Id = {}", id);// 5. 将结果存储到数据库或缓存中// 修保存到数据库中的测试结果version = version + 1;QuestionTest questionTest = new QuestionTest();questionTest.setVersion(version);questionTest.setId(id);questionTest.setQuestionId(questionId);questionTest.setUserId(userId);questionTest.setUserCode(userCode);questionTest.setCodeLanguage(codeLanguage);questionTest.setCurrentJudgeCase(JSONUtil.toJsonStr(currentJudgeCase));questionTest.setUserJudgeCase(JSONUtil.toJsonStr(userJudgeCase));
//            System.out.println("QuestionTest:"+questionTest);questionFeignClient.updateQuestionTestById(questionTest);// 6. 手动确认消息channel.basicAck(deliveryTag, false);

相关文章:

消息队列导致数据库数据读取不一致解决方案

我使用的是在数据库添加一个版本字段&#xff0c;记录版本&#xff0c;保证版本一致性&#xff0c;就能保证每次读取的是需要的内容。 具体问题&#xff1a;使用消息队列时&#xff0c;发送方给接收方发送消息&#xff0c;接收方修改了数据库的同时发送方查询数据库&#xff0…...

如何利用 Zeabur 实现 OceanBase 的一键部署

引言 Zeabur 是一个功能强大且即开即用的自动化部署平台&#xff0c;它不仅能迅速部署多种应用&#xff0c;还支持一键安装 MySQL、PostgreSQL 等数据库服务。 Zeabur 拥有众多国内外用户&#xff0c;如 AFFiNE、Bytebase 等企业客户&#xff0c;以及大量全栈和独立开发者。将…...

计算机网络进化论:从比特流到量子通信的深层解构

第一章 物理媒介与链路层(1960-1970) 1.1 比特流物理编码 // 曼彻斯特编码实现 vector<bool> manchester_encode(uint8_t byte) {vector<bool> bits;for(int i=7; i>=0; --i) {bool bit = (byte >> i) & 1;bits.push_back(bit); // 前半周期bits…...

超参数优化算法:scikit-opt库、Scikit-Optimize库

1 scikit-opt库&#xff1a;https://www.cnblogs.com/luohenyueji/p/18333387 https://blog.csdn.net/weixin_45750972/article/details/124683402 a 差分进化算法 (Differential Evolution)&#xff1a;一种基于群体搜索的优化算法&#xff0c;通过模拟生物进化的过程来寻找最…...

go语言学习教程推荐,零基础到做项目

一、基础入门阶段 官方教程&#xff08;免费&#xff09; • A Tour of Go&#xff1a;交互式入门教程&#xff0c;边学边练 • Go by Example&#xff1a;通过300代码片段学习语法 入门书籍 • &#x1f4d8;《Go语言圣经》中文版&#xff08;免费在线阅读&#xff09;&#…...

【商城实战(30)】从0到1搭建商城数据分析功能,开启数据驱动增长引擎

【商城实战】专栏重磅来袭&#xff01;这是一份专为开发者与电商从业者打造的超详细指南。从项目基础搭建&#xff0c;运用 uniapp、Element Plus、SpringBoot 搭建商城框架&#xff0c;到用户、商品、订单等核心模块开发&#xff0c;再到性能优化、安全加固、多端适配&#xf…...

(hash表+vector 数位和相等数对的最大和)leetcode 2342

一定要断点调试看看数据对不对的上&#xff01;&#xff01;&#xff01;不然很容易弄不清楚值和下标 这个题意思是在nums中找出相同数位和的值 如 数位和为7 nums中符合要求的有 43&#xff0c;7 在这些数中选两个相加取最大值&#xff0c;再与其他数位和取得的相加最大值比…...

c++中字符串string常用的函数

在C中&#xff0c; std::string 类有许多常用函数&#xff0c;以下是一些常见的&#xff1a; 1. length() 或 size() &#xff1a;返回字符串的长度&#xff08;字符个数&#xff09;&#xff0c;二者功能相同。例如&#xff1a; #include <iostream> #include <str…...

NO.39十六届蓝桥杯备战|结构体八道练习|加号小于号运算符重载|自定义排序(C++)

加号运算符重载_牛客题霸_牛客网 #include <iostream> using namespace std;class Time {public:int hours; // 小时int minutes; // 分钟Time() {hours 0;minutes 0;}Time(int h, int m) {this->hours h;this->minutes m;}void show() {cout <<…...

kmp报错→Cannot find skiko-windows-x64.dll.sha256

1、前言 学习kmp&#xff08;Kotlin MultiPlatform简称&#xff09;过程中报了错误&#xff0c;这个报错在直接运行desktop的main方法才会出现&#xff0c;用gradle运行却不会报错&#xff0c;新建的kmp项目也不会出现&#xff0c;我学习的写了一些代码的项目才会出现。   运…...

Cocos Creator Shader入门实战(四):预处理宏定义和Chunk

引擎&#xff1a; 3.8.5 您好&#xff0c;我是鹤九日&#xff01; 回顾 学习Shader&#xff0c;前期是让人烦躁无味的&#xff0c;后期可能就是各种的逻辑让人抓耳挠腮。 一成不变的内容&#xff1a;遵循引擎设定的规则&#xff0c;理解引擎要求的规范。 这里&#xff0c;简单…...

K8S快速部署

前置虚拟机环境正式部署BUG解决 前置虚拟机环境 每个虚拟机配置一次就好 #关闭防火墙 systemctl stop firewalld systemctl disable firewalld #关闭 selinux sed -i s/enforcing/disabled/ /etc/selinux/config # 永久 setenforce 0 # 临时 #关闭 swap swapoff -a # 临时 vi…...

汽车PKE无钥匙进入系统一键启动系统定义与原理

汽车智能钥匙&#xff08;PKE无钥匙进入系统&#xff09;一键启动介绍 系统定义与原理 汽车无钥匙进入系统&#xff0c;简称PKE&#xff08;Passive Keyless Entry&#xff09;&#xff0c;该系统采用了RFID无线射频技术和车辆身份编码识别系统&#xff0c;率先应用小型化、小…...

使用 VLOOKUP 和条件格式在 Excel 中查找并标红匹配的串号

使用 VLOOKUP 和条件格式在 Excel 中查找并标红匹配的串号 你的步骤非常详细且清晰&#xff0c;能够帮助用户在 Excel 中通过 VLOOKUP 和条件格式来查找并标红匹配的串号。以下是对你提供的步骤的简要总结和补充说明&#xff1a; 1. 添加“是否匹配”列 在 a.xlsx 中新增一列…...

WPF程序使用AutoUpdate实现自动更新

AutoUpdate.NET使用 一、AutoUpdater.NET 简介 AutoUpdater.NET 是一个开源库&#xff0c;支持从各种源&#xff08;如GitHub、FTP、HTTP服务器等&#xff09;下载并安装更新。它提供了灵活的配置选项&#xff0c;允许开发者根据需求定制更新检查逻辑和用户体验。 二、安装 …...

Dify平台离线镜像部署

Dify 是一款开源的大语言模型(LLM) 应用开发平台。它融合了后端即服务&#xff08;Backend as Service&#xff09;和 LLMOps 的理念&#xff0c;使开发者可以快速搭建生产级的生成式 AI 应用。即使你是非技术人员&#xff0c;也能参与到 AI 应用的定义和数据运营过程中。 前提…...

每日Attention学习28——Strip Pooling

模块出处 [CVPR 20] [link] Strip Pooling: Rethinking Spatial Pooling for Scene Parsing 模块名称 Strip Pooling (SP) 模块结构 模块特点 本质是空间注意力的一种使用横/纵两个方向的条形池化获得一维方向上的重要程度&#xff0c;结合后便可以扩展至二维方向 模块代码 …...

Android Room 框架公共模块源码深度剖析(四)

一、引言 在 Android 开发中&#xff0c;数据持久化是一个常见的需求。Android Room 框架作为 Android Jetpack 组件的一部分&#xff0c;为开发者提供了一个抽象层&#xff0c;使得在 SQLite 数据库上进行数据操作变得更加简单和高效。Room 框架包含多个模块&#xff0c;其中…...

玩转python:通俗易懂掌握高级数据结构-collections模块之UserDict

引言 UserDict是Python中collections模块提供的一个强大工具&#xff0c;它是dict的封装类&#xff0c;允许用户自定义字典的行为。通过继承UserDict&#xff0c;开发者可以轻松扩展字典的功能&#xff0c;实现自定义的字典逻辑。本文将详细介绍UserDict的关键用法和特性&…...

ollama docker设置模型常驻显存

参考&#xff1a; https://github.com/ollama/ollama/issues/5272 https://deepseek.csdn.net/67cfd7c93b685529b708fdee.html 通过-e传入环境变量&#xff0c;ollama运行&#xff1a; docker run -d --gpusall -e OLLAMA_KEEP_ALIVE-1 -v ollama:/root/.ollama -p 11434:114…...

双3060、Ubuntu22.04、cuda12.8安装deepseek 32b-Q8

以下是针对双RTX 3060显卡&#xff08;12GB显存&#xff09;在Ubuntu 22.04系统部署DeepSeek-R1-32b-qwen-distill-q8模型的完整流程&#xff0c;结合最新技术规范与魔塔社区资源&#xff1a; 一、驱动与CUDA环境配置 1. 禁用开源驱动 bash sudo tee /etc/modprobe.d/blackli…...

无再暴露源站!群联AI云防护IP隐匿方案+防绕过实战

一、IP隐藏的核心原理 群联AI云防护通过三层架构实现源站IP深度隐藏&#xff1a; 流量入口层&#xff1a;用户访问域名解析至高防CNAME节点&#xff08;如ai-protect.example.com&#xff09;智能调度层&#xff1a;基于AI模型动态分配清洗节点&#xff0c;实时更新节点IP池回…...

Chrome 调试器第二次连接不上?

一、连接不上 当使用 chrome_options.add_experimental_option("debuggerAddress", "127.0.0.1:9222") 连接 Chrome 调试器时&#xff0c;调试一次后就连不上&#xff0c;可能由以下几种原因导致&#xff1a; 1. Chrome 实例关闭 原因&#xff1a;在调试…...

【深度学习|目标检测】YOLO系列anchor-based原理详解

YOLO之anchor-based 一、关于anchors的设置二、网络如何利用anchor来训练关于register_buffer训练阶段的anchor使用推理阶段的anchor使用 三、训练时的正负样本匹配静态策略&#xff1a;跨分支采样跨anchor采样跨grid采样 动态策略 总结起来其实就是&#xff1a;基于anchor-bas…...

Linux 入门:权限的认识和学习

目录 一.shell命令以及运行原理 二.Linux权限的概念 1.Linux下两种用户 cannot open directory .: Permission denied 问题 2.Linux权限管理 1).是什么 2).为什么&#xff08;权限角色目标权限属性&#xff09; 3).文件访问者的分类&#xff08;角色&#xff09; 4).文…...

搭建opensbi+kernel+rootfs及基本设备驱动开发流程

目录 一.编译qemu 运行opensbikernelrootfs 1.编译qemu-9.1.1 2.安装riscv64编译器 3. 编译opensbi 4.编译kernel 5.编译rootfs 设备驱动开发流程 1.安装 RISC-V 交叉编译工具链 2.驱动开发准备 3.编写简易中断控制器驱动&#xff08;PLIC&#xff09;​ 4.配置内核…...

QT非UI设计器生成界面的国际化

目的 UI设计器生成界面的国际化&#xff0c;比较容易实现些&#xff0c;因为有现成的函数可以调用&#xff0c;基本过程如下&#xff1a; void MainWindow::on_actLang_CN_triggered() {//中文界面qApp->removeTranslator(trans);delete trans;transnew QTranslator;trans…...

python | 输入日期,判断这一天是这一年的第几天

题目&#xff1a; 使用 python 编程&#xff0c;实现输入日期&#xff0c;判断这一天是这一年的第几天? 具体实现代码如下&#xff1a; import datetime year input(请输入年份&#xff1a;) month input(请输入月份&#xff1a;) day input(请输入天&#xff1a;) date…...

openai 标准化协议 Structured Outputs 具体示例教程

Structured Outputs 具体示例教程 场景&#xff1a;个人财务管理助手 假设我们要构建一个 AI 助手&#xff0c;帮助用户记录和管理个人财务支出。用户可以输入自然语言描述&#xff08;如“昨天我花了50元买了午餐”&#xff09;&#xff0c;助手将提取关键信息并以结构化 JS…...

单片机开发资源分析的实战——以STM32F103C8T6为例子的单片机资源分析

目录 第一点&#xff1a;为什么叫STM32F103C8T6 从资源手册拿到我们的对STM32F103C8T6的资源描述 第二件事情&#xff0c;关心我们的GPIO引脚输出 第三件事情&#xff1a;去找对应外设的说明部分 前言 本文章隶属于项目&#xff1a; Charliechen114514/BetterATK: This is…...