RyanKKLam 2015-09-20 07:50 采纳率: 0%
浏览 3339

Mybatis select 没有获取更新数据 (缓存 ?)

写了一个简单的mybatis demo,没有集成其他事务管理,对接mysql数据库。

在表file_resources的mapper里面定义了一个这样的嵌套sql , 里面用到了 postinfo 、 poststatus两个表

</select>
   <select id="selectPendingPostItemCount" resultType="java.lang.Integer" flushCache="true" useCache="false">
    select count(*)
    from file_resources
    where objectName in (SELECT PostID  FROM postinfo where PostLink not in (select PostLink from poststatus) 
                            group by postid having count(1) = 1) 
  </select>

我有另外一个线程去跑一些处理,是做完一条就commit一条的,poststatus的数据会不断增多,这样上面sql获取的count是不断减少的,我在mysql workbench控制台跑这条sql,count是不断会减少的。

但是当我开一个新线程在程序里跑count那条sql时,发觉无法获取到更新的数据,只有第一次跑时返回正确的count,之后这个count都没有改变(但在mysql workbench控制台跑,是不断减少的)

最开始的版本是这样的,sqlsession是用单例获取重用的open session,一开始就取好mapper,然后慢慢循环去跑sql,无法获取到更新count。

        SqlSession refreshSession = SessionFactorySingleton.getInstance().getOpenSession();
        FileResourcesMapper fileMapper = refreshSession.getMapper(FileResourcesMapper.class);
        while(true){
            int count = fileMapper.selectPendingPostItemCount();
            Thread.sleep(50000);
        }

直觉怀疑是缓存的问题,谷哥度娘之,然后作了几点修改,问题依旧。
1: 没有用单例获取sqlsession,而是重新按SqlSessionFactoryBuilder方法获取新的open session,并每次重新取mapper去跑select,问题依旧。
2:每次run完selection之后跑clearCache() 跟commit,问题依旧。
3:修改mapper ,在selectPendingPostItemCount定义 flushCache跟useCache去控制一二级缓存,问题依旧。

   </select>
   <select id="selectPendingPostItemCount" resultType="java.lang.Integer" flushCache="true" useCache="false">
    select count(*)
    from file_resources
    where objectName in (SELECT PostID  FROM postinfo where PostLink not in (select PostLink from poststatus) 
                            group by postid having count(1) = 1) 
  </select>
 //      SqlSession refreshSession = SessionFactorySingleton.getInstance().getOpenSession();
        SqlSession refreshSession = getNewOpenSession(); //get new open session from new SqlSessionFactoryBuilder
        FileResourcesMapper fileMapper = refreshSession.getMapper(FileResourcesMapper.class);
        while(true){
            int count = fileMapper.selectPendingPostItemCount();
            refreshSession.clearCache();
            refreshSession.commit();
            fileMapper = refreshSession.getMapper(ColafileResourcesMapper.class);
            Thread.sleep(50000);
        }

这之后,我就去看了看缓存跟sql执行的代码。

CachingExecutor 里面MappedStatement取出来的cache都是null的 , BaseExecutor里面的clearLocalCache()也有被call起来
最后BaseExecutor也involve了SimpleExecutor的doQuery(),里面就是jdbc的基本操作,PreparedStatementHandler的execute方法去执行sql。已经与缓存没有什么关系。
但是返回的值就是旧的。。。。。

打开的debug log可以证实sql已经提交连接数据库,同时我也在后台看到了sql语句的执行,但是从程序那边读取的返回值就是死活没有更新到。(在后台mysql界面直接跑同一条sql是有更新的)

我们现在的方法是每次跑mapper的selectPendingPostItemCount() 方法之后,就去直接把连接关闭掉(refreshSession.close())。下一次查询时重新取过sqlsession去跑select,是可以的。

有这方便经验的童鞋知道是什么问题麽 ?或者 可以给点意见或方向给我们去排查一下,感激不尽。

现在在看是不是namespace的问题,就是里面嵌套了其他file,是postinfo 、 poststatus两个表被缓存了 ?

 <mapper namespace="com.mybatis.inter.FileResourcesMapper" >
  <resultMap id="BaseResultMap" type="com.mybatis.model.FileResources" >
    <id column="objectLink" property="objectlink" jdbcType="VARCHAR" />
。。。。。。
  • 写回答

1条回答

  • 「已注销」 2015-09-20 07:57
    关注

    额。。。建议楼主把出错的问题描述清楚,再把出错的信息贴出来方便大家查看,再者我们没有你的代码,无法帮你测试,只有看到出错的问题了,才能根据经验帮你猜测一下

    评论

报告相同问题?

悬赏问题

  • ¥15 C++使用Gunplot
  • ¥15 这个电路是如何实现路灯控制器的,原理是什么,怎么求解灯亮起后熄灭的时间如图?
  • ¥15 matlab数字图像处理频率域滤波
  • ¥15 在abaqus做了二维正交切削模型,给刀具添加了超声振动条件后输出切削力为什么比普通切削增大这么多
  • ¥15 ELGamal和paillier计算效率谁快?
  • ¥15 file converter 转换格式失败 报错 Error marking filters as finished,如何解决?
  • ¥15 Arcgis相交分析无法绘制一个或多个图形
  • ¥15 关于#r语言#的问题:差异分析前数据准备,报错Error in data[, sampleName1] : subscript out of bounds请问怎么解决呀以下是全部代码:
  • ¥15 seatunnel-web使用SQL组件时候后台报错,无法找到表格
  • ¥15 fpga自动售货机数码管(相关搜索:数字时钟)