【问题标题】:Elusive Hibernate Second Level Cache难以捉摸的休眠二级缓存
【发布时间】:2014-07-22 14:23:29
【问题描述】:

我对以下试图避免 Hibernate 缓存的代码的输出感到非常困惑。

我打开一个新的 Hibernate 会话,运行一个查询,并在它在指定的断点处停止时检查结果。在继续执行之前,我去 MySQL 并删除或添加一行。当我继续执行时,查询仍然显示旧数据和旧行计数,尽管在休眠缓存上调用了evictAllRegions(),而普通的 JDBC 查询显示更新的计数(如预期的那样)。

hibernate.cache.use_second_level_cachehibernate.cache.use_query_cache 设置为 false 并没有帮助。我想这应该没关系,因为缓存是手动清除的。

那么,为什么 Hibernate 没有访问数据库?

Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/mydb...");

for (int i = 0; i < 15; i++) {
    session = HibernateUtil.getSessionFactory().openSession();

    // Old data keeps being returned
    list = session.createCriteria(Language.class).list();

    // JDBC fetches expected count
    Statement statement = conn.createStatement();
    ResultSet resultSet = statement.executeQuery("select * from language");
    int x = 0;
    while (resultSet.next()) x++; // count the rows

[Breakpoint here]
    session.close();
    HibernateUtil.getSessionFactory().getCache().evictAllRegions();
}

【问题讨论】:

  • 你检查过你的事务隔离了吗?
  • 如果这很重要,它不应该也影响 JDBC 调用吗?无论如何,它在 MySQL 服务器上是可重复读取的。

标签: java hibernate


【解决方案1】:

我相信这是在 MySQL 中将事务隔离级别设置为 REAPEATABLE-READ 的结果。

当您从代码发出查询时,MySQL 会创建语言表的快照,并在该事务的其余部分继续呈现该快照。因此数据有效地缓存在 MySQL 而不是 Hibernate。

http://dev.mysql.com/doc/refman/5.0/en/set-transaction.html#isolevel_repeatable-read

【讨论】:

    猜你喜欢
    • 2010-10-20
    • 2017-07-05
    • 2011-07-08
    • 1970-01-01
    • 2010-10-29
    • 2019-04-02
    • 2023-03-03
    • 1970-01-01
    相关资源
    最近更新 更多