2015-03-31 61 views
8

我有一个web应用程序,我一直在使用Spring Data从iBATIS 2慢慢迁移到JPA。为什么iBATIS即使禁用了缓存,也会给出陈旧的结果?

大多数情况下,事情进展顺利,我一次只为一个域对象迁移DAO。然而,最近引起我注意的一个问题是,网站的某些部分显示陈旧的结果列表。

例如,我有一个“票证”部分,其中显示了打开票证的列表,并允许您在单独的页面上查看特定票证。当我创建新票时,我可以正确查看该票在其特定页面上。然而,直到稍后的一段时间,公开票单才似乎没有显示这张新票。

事情我已经试着排除:

  • 我看到这个问题甚至在系统禁用
  • 我看到,甚至当我在iBATIS的配置设置cacheModelsEnabled="false"这个问题MySQL的查询缓存。
  • 即使我从我的sqlMap文件中完全删除<cacheModel>元素和cacheModel="x"属性,我仍然看到此问题。
  • 只要我重新启动应用程序,我就会看到最新的结果。
  • 当我执行查询时,iBATIS应该在MySQL客户端运行,I do查看iBATIS结果中缺少的新票。
  • 当我使用Spring MVC和Spring Data JPA嘲笑一个简单的票单时,我do看到新票。

我也试图排除某种奇怪的交易状态与iBATIS,但似乎并没有任何交易在这里被使用。

我错过了什么?还有什么我应该试图弄清楚这一点?或者,我应该优先使用Spring Data JPA来完全替换iBATIS层,而这似乎不受此问题的困扰?

UPDATE

现在我已经经历了很多我最近改变了与git bisect,我已经将范围缩小到介绍Spring的org.springframework.orm.jpa.support.OpenEntityManagerInViewFilter的变化。

所以,看起来有些交易比它应该活的更长。我会添加更多日志记录以查看是否可以确认,然后查找避免使用该过滤器的方法。

+0

你好Pioto,看看这有助于https://groups.google.com/forum/#!searchin/mybatis-user/stale$20results|sort:relevance/mybatis-user/vhYQ6_QaMsI/ETGW-8cZStsJ – 2015-04-10 06:49:00

+0

该链接似乎被打破,至少对我而言。您是否愿意在回答中至少解释您在那里找到的内容? – pioto 2015-04-10 14:37:54

回答

0

所以,似乎一个事物的组合结束了在这里发生:

  1. 我的大部分代码没有明确使用事务。
  2. 我在某些时候更改为使用Tomcat's JDBC Connection Pool,默认情况下,连接返回到池时不会重置autocommit。不过,我期望我的旧版DBCP系统能够隐含这样做。
  3. OpenEntityManagerInViewFilter的引入可能导致某个点调用了SET autocommit=0,如果没有更改,则后面没有相应的SET autocommit=1
  4. 偶然或者可能是某种设计,将新记录插入数据库然后立即检索并显示出来的代码似乎与显示我的记录列表的代码相比,得到了不同的Connection
  5. 默认的MySQL事务隔离级别REPEATABLE-READ意味着我的列表显示了旧的结果。

的修复,我发现,这似乎是在我的测试工作,到目前为止,是这些defaultAutoCommitjdbcInterceptors属性添加到我的连接池的配置:

<Resource name="jdbc/DB" auth="Container" type="javax.sql.DataSource" 
    factory="org.apache.tomcat.jdbc.pool.DataSourceFactory" 
    ... 
    defaultAutoCommit="true" jdbcInterceptors="ConnectionState;StatementFinalizer" /> 
0

如果您在选择,插入,选择相同的SqlSession, 然后SqlSession缓存导致此问题。在insert:sqlSession.clearCache()后,您将需要手动清除缓存 。

+0

我在我的类路径中没有看到任何SqlSession ...没有显式的会话或事务发生在这里,我们只有一个对象在单个SqlMapClient对象上运行,调用insert()等......但是,它可能有可能我最近改变了一些东西,以至于SqlMapClient可能比以前更久了(把我的Dao对象从一个方法本地的对象移动到我的控制器的私有类字段)... – pioto 2015-04-10 14:51:18

+0

所以你正在阅读来自文件的配置信息和创建SQLMap对象以供您的应用程序使用,是否正确理解? – 2015-04-10 15:02:54

+0

正确;我们做'SqlMapClientBuilder.buildSqlMapClient(reader);',或者等价的使用Spring bean,' ...' – pioto 2015-04-10 16:42:11

相关问题