关于Hibernate缓存机制的一些说明?

时间:2011-09-20 17:10:29

标签: hibernate

我对通过hibernate缓存教程发现的语句有疑问。

Statement1: - 第一级缓存始终与Session对象关联。 Hibernate默认使用此缓存。

问题1: -
由于此缓存默认保存会话方法的所有结果,例如load,get等。由于将所有对象保留在seeion中,它不会成为主要的内存问题吗?

问题2: -
我们是否需要默认启用此缓存或其缓存?如果需要,我可以禁用一级缓存吗?如果是的话怎么样?

以下问题适用于第一级和第二级缓存

问题3: -
如果我从缓存中获取相同的对象(比如我在同一会话中使用customerid 1加载对象客户两次),则从缓存返回的两个对象将具有与缓存中的对象不同的引用。 对吗?因为如果我更新客户对象中的某个字段,除非调用save / update方法,否则它不应反映在缓存中。

问题4: -
根据我的理解,如果我们尝试从此缓存中第二次从id获取客户对象,它将返回相同的旧对象,即使它们之间已更新。 我们怎样才能确保它是否得到更新它从数据库中读取否则从缓存中读取?我想我们可以使用类似 EHCache

等类的读写缓存策略

问题5: - 关于查询缓存
我读到了这句话: - 查询中的更新经常发生。因此,对于查询缓存,需要两个缓存区域。

用于存储结果。(缓存标识符值和值类型的结果仅)。 用于存储最新的更新。

我认为“查询中的更新经常发生”意味着我们通常会更改某些参数值,例如select * from customer where custid=?因此id将针对不同的客户ID进行更改。因此查询缓存将保留每个查询(以及参数)和每个查询返回的结果。

从右?但不确定为什么我们需要两个缓存区域进行查询缓存?

1 个答案:

答案 0 :(得分:4)

AFAIK
答案01:

Hibernate缓存加载的对象,以避免不必要的数据库访问。避免持久性上下文的最简单方法是使用StatelessSession。无状态Hibernate会话没有脏检查责任,因此可以满足您没有第一级缓存(Persistant Context)的要求。

回答02:

  1. 您不必启用第一级缓存
  2. 回答03

    1. 如果一个对象使用其标识在同一会话中加载两次,则无论是否启用了二级缓存,Hibernate都会确保返回相同的对象。让我澄清一下二级缓存不会缓存对象的实例。它维护实例的序列化(不完全)版本。 以下link给出了hibernate二级缓存结构的简要说明。
    2. 我很抱歉,但我不理解“更新客户对象并且没有反映在缓存中”背后的概念。我希望该链接澄清您的问题。

      回答04

      1. 如果未正确配置,则会出现从缓存中提取的陈旧数据的问题。 如果未发生缓存上的到期时间,则将获取状态数据。可以使用Session.evict()进行驱逐,但是您可能无法清楚地知道需要驱逐哪些数据。因此,缓存应始终是优化数据库访问的最后一步。 通过重新评估收集关系的关联和获取计划,可以实现良好的优化水平,以避免N + 1选择问题,同时避免。·
        EHCache 为无法更新的数据提供read-write缓存策略 符合事务read committed保护。这是避免dirty reads,但无法帮助repeatable reads
      2. 查看EHCache配置here

        回答05:查询缓存

        1. 查看这些链接,以便更好地理解会话缓存和查询缓存    A. Session Cache
             B. Second Level Cache
             C. Query Cache

        2. Checkout this link,它简要/简单地解释了查询缓存的结构。

        3. 希望这有帮助。