找回密码
 立即注册
首页 业界区 安全 记一次 MyBatis 缓存引发的问题

记一次 MyBatis 缓存引发的问题

袁可佳 6 天前
故事背景  

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

    了解问题之后总结故障现象如下:
   1. 第一次添加的物料组显示正常。
  1. 物料组_1
  2.   |---- 物料_11
  3.   |---- 物料_12
复制代码
    2. 第二次添加相同的物料组显示不正常,但是物料组包含的行数正确。
  1. 物料组_1
  2.   |---- 空
  3.   |---- 空
复制代码
    3. 添加不同物料组则显示正常。
  1. 物料组_2
  2.   |---- 物料_21
  3.   |---- 物料_22
复制代码
查找原因

    首先,检查从后台发送到前台的 json 数据。json 数据形式如下:
  1. 物料组_1
  2.   |---- 空
  3.   |---- 空
复制代码
    OK,这里前台显示是正常的,json 数据确实是空。
    然后,检查后台返回的对象数据。数据形式如下:
  1. 物料组_1
  2.   |---- 物料_11
  3.   |---- 物料_12
复制代码
    OK,这里后台返回数正常的,数据确实有内容。
    然后我就尬住了,前台后台都正常。那么问题在哪里?
    接下来只能去对比后台数据的第一次和第二次添加物料组的区别了。对比了很久,发现第一次和第二次添加的数据内容在后台都是完全相同的。只要发送到前端,第二次添加的内容就变成空了。目前可以定位问题时出在后台对象到前台 json 的转换上。
    在仔细对比不同物料组发现,不同物料组的对象 id 都不同,相同物料组的对象 id 都相同。于是猜想是不是同一对象只会序列化一次?因为我也不是做 java 的,对框架不熟悉需要验证猜想。那么就想办法让每次查询返回不同的对象就行了。度娘之后发现,原来 MyBatis 在 select 查询时会缓存查询结果。致使相同参数的查询会返回同一个对象。又由于序列化时每个对象只会序列化一次(这里我没有深究,只是结果上看是这样),这才导致的上述问题。好了现在问题已经非常清楚了接下来就是解决问题。
解决办法

    SqlSession 提供了一个清除查询缓存的方法。当需要查询返回不同对象时,清除一次之前的缓存,这样新的查询就能返回新的对象。
代码如下:
  1. import org.apache.ibatis.session.SqlSession;
  2. @Autowired
  3. private SqlSession sqlSession;
  4. sqlSession.clearCache();  // 在需要返回不同实例的 select 前 添加,以清除之前查询的缓存
复制代码
    在对应位置修改代码之后,更新系统检查查询结果。问题解决。

来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
您需要登录后才可以回帖 登录 | 立即注册