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

记一次 MyBatis 缓存引发的问题

故事背景

拿到一个JAVA开发的管理系统。用户反馈一了个问题。就是在查询 bom 表时相同商品组的第二次添加显示内容的为空,但是行数正确。第一次添加的数据则是完全正常。于是更详细的了解问题现象。

在这里插入图片描述

问题现象

了解问题之后总结故障现象如下:

1. 第一次添加的商品组显示正常。

商品组_1|---- 商品_11|---- 商品_12

2. 第二次添加相同的商品组显示不正常,但是商品组包含的行数正确。

商品组_1|---- 空|---- 空

3. 添加不同商品组则显示正常。

商品组_2|---- 商品_21|---- 商品_22

查找原因

首先,检查从后台发送到前台的 json 数据。json 数据形式如下:

商品组_1|---- 空|---- 空

OK,这里前台显示是正常的,json 数据确实是空。

然后,检查后台返回的对象数据。数据形式如下:

商品组_1|---- 商品_11|---- 商品_12

OK,这里后台返回数正常的,数据确实有内容。

然后我就尬住了,前台后台都正常。那么问题在哪里?

接下来只能去对比后台数据的第一次和第二次添加商品组的区别了。对比了很久,发现第一次和第二次添加的数据内容在后台都是完全相同的。只要发送到前端,第二次添加的内容就变成空了。目前可以定位问题时出在后台对象到前台 json 的转换上。

在仔细对比不同商品组发现,不同商品组的对象 id 都不同,相同商品组的对象 id 都相同。于是猜想是不是同一对象只会序列化一次?,对框架不熟悉需要验证猜想。那么就想办法让每次查询返回不同的对象就行了。度娘之后发现,原来 MyBatis 在 select 查询时会缓存查询结果。致使相同参数的查询会返回同一个对象。又由于序列化时每个对象只会序列化一次(这里我没有深究,只是结果上看是这样),这才导致的上述问题。好了现在问题已经非常清楚了接下来就是解决问题。

解决办法

SqlSession 提供了一个清除查询缓存的方法。当需要查询返回不同对象时,清除一次之前的缓存,这样新的查询就能返回新的对象。

代码如下:

import org.apache.ibatis.session.SqlSession;@Autowired
private SqlSession sqlSession;sqlSession.clearCache();  // 在需要返回不同实例的 select 前 添加,以清除之前查询的缓存

在对应位置修改代码之后,更新系统检查查询结果。问题解决。

http://www.xdnf.cn/news/236125.html

相关文章:

  • 高级测试工程师 的面试题汇总
  • 实验-单总线温度采集与显示(汇编语言与接口技术)
  • 视觉问答大模型速递:Skywork-R1V2-38B
  • 【人工智能】深入探索Python中的自然语言理解:实现实体识别系统
  • 第二部分:赤色的世界
  • 提高设计的综合性能
  • ESP32开发之freeRTOS的信号量
  • 免费在Colab运行Qwen3-0.6B——轻量高性能实战
  • Learning vtkjs之ImplicitBoolean
  • Java大师成长计划之第8天:Java线程基础
  • 树状结构转换工具类
  • 沙箱逃逸-通过题解了解沙箱逃逸
  • Flow Matching 是什么?
  • 如何做表征对齐?
  • Kettle下载安装教程
  • C# 异步详解
  • 探索MySQL InnoDB:事务、日志与锁的奥秘
  • 从实列中学习linux shell5: 利用shell 脚本 检测硬盘空间容量,当使用量达到80%的时候 发送邮件
  • MCP 自定义python实现server服务,支持离线调用和远程接口访问形式
  • 【IP101】图像处理基础:从零开始学习颜色操作(RGB、灰度化、二值化、HSV变换)
  • Kaamel白皮书:OpenAI 在安全方向的实践
  • Vulkan 学习(16)---- 使用 VertexBuffer
  • Python魔法函数深度解析
  • 关于epoch、batch_size等参数含义,及optimizer.step()的含义及数学过程
  • pinia实现数据持久化插件pinia-plugin-persist-uni
  • 10、属性和数据处理---c++17
  • 突破SQL注入字符转义的实战指南:绕过技巧与防御策略
  • 《Ultralytics HUB:开启AI视觉新时代的密钥》
  • Stack--Queue 栈和队列
  • 前端基础之《Vue(13)—重要API》