【问题标题】:about hibernate cache store关于休眠缓存存储
【发布时间】:2015-12-19 14:28:15
【问题描述】:

众所周知,hibernate 有 L1 和 L2 缓存。现在我对他们的商店有一些疑问:

  1. 如果 L2 缓存启用并且 L1 和 L2 缓存中没有命中,则休眠将查询 DB。但是,从 DB 中获取结果后,它会将结果仅存储在 L2 缓存中还是同时存储在 L1 和 L2 中或其他任何地方?
  2. 如果启用了 L2 缓存并且一个会话的 L1 有结果但 L2 没有,那么休眠会将这个结果从 L1 复制到 L2?
  3. 如果 L2 缓存启用并且 L2 有结果但 L1 没有,那么休眠会将其从 L2 复制到 L1?

更新

4.如果我有下一个代码并且没有 L2 缓存和查询缓存:

List<Student> persons = session.createQuery("from Student").list();

List<Student> students = session.createQuery("from Student").list();

为什么hibernate会查询数据库两次?不是有L1缓存,所以第一次只查询DB?

提前致谢!

【问题讨论】:

    标签: hibernate caching


    【解决方案1】:

    如果启用了 L2 缓存并且 L1 和 L2 缓存中没有命中,那么 hibernate 将查询 DB。但是,从 DB 获取结果后,它会将结果存储在 L2 缓存中还是同时存储在 L1 和 L2 中或其他任何地方?

    这完全取决于您尝试执行的操作类型

    1. EntityManager.find()

      在这种情况下,只要实体配置了@Cachable 并启用了 L2 缓存,您从这些查找中收到的任何结果都将缓存在 L1 和 L2 中,并将根据您的 L2 缓存保留在 L2 中配置。

    2. EntityManager.createQuery()

      在这种情况下,它不仅取决于实体是否配置了@Cachable 并且启用了二级缓存,还取决于是否通过配置属性@ 全局启用了查询缓存 987654325@ 或者您是否指定特定查询可在运行时通过query.setCachable(true) 进行缓存。

      如果查询未缓存并且后续会话运行相同的查询,则不会查询 L2 缓存,因为查询不知道哪些实体标识符映射到正在执行的查询,因此必须通过以下方式查询数据源SQL 查询。

    如果启用了 L2 缓存并且一个会话的 L1 有结果但 L2 没有结果,那么 hibernate 会将这个结果从 L1 复制到 L2?

    看我上面的回答。

    如果你执行了entityManager.find(),那么是的,如果它是一个可缓存的实体实例,那么 L2 将与你刚刚查询的实体的属性数据相结合。

    如果您执行了entityManager.createQuery(),这将取决于是否启用了查询缓存。如果未启用,则不会将任何数据复制到 L2。如果启用了查询缓存,则 L2 将如上所示进行相应更新。

    如果启用 L2 缓存并且 L2 有结果但 L1 没有,那么 hibernate 会将其从 L2 复制到 L1?

    L1 缓存将始终具有附加实体的活动状态,无论状态是从 L2 缓存、数据存储还是两者的组合中获取。

    如果我在一个会话中有 2 个“session.createQuery(..).list()”,为什么 hibernate 会查询 DB 两次?不是有L1缓存,那么第二个“session.createQuery(...).list()”应该从L1获取结果?

    我将假设两个查询都执行相同的 HQL 语句,因为这是查询缓存在此用例中工作的要求。

    仅仅因为 Hibernate 在查询期间向数据库发出查询并不意味着没有查询或使用 L2 缓存。

    首先,两个查询都使用setCachable(true) 来启用查询缓存吗?

    假设在您的第一个list() 执行时查询缓存和实体缓存为空,hibernate 将相应地填充实体和查询缓存。在第二次查询期间,它会查询 L2 缓存,只要实体或查询缓存都没有过期,它就会从 L2 重新水化。

    请务必注意,如果查询缓存在您的实体缓存结果之后过期,这可能会产生一些性能瓶颈问题,因为 L2 查询缓存会指示要包含哪些实体,休眠会发现它们已过期并重新发布数据库按 id 查询每个过期实体。

    【讨论】:

    • The L1 cache will always have the active state of an attached entity, regardless of whether the state was fetched from the L2 cache, the datastore, or a combination of both,什么意思?
    • If I have 2 "session.createQuery(..).list()" within one session, why hibernate will query DB twice? Doens't it has L1 cache, then the second "session.createQuery(...).list()" should get the result from the L1?,我已经修改了这个问题,请看我的更新。
    猜你喜欢
    • 2012-03-14
    • 1970-01-01
    • 2016-08-13
    • 2016-01-05
    • 2020-09-05
    • 1970-01-01
    • 2012-04-29
    • 2015-01-05
    • 2011-11-18
    相关资源
    最近更新 更多