Hibernate缓存参考

时间:2011-01-31 15:36:02

标签: hibernate caching jpa

我正在寻找一个简单,完整,简洁的缓存列表,您将使用Hibernate编写JPA代码。

特别是我想知道每个缓存,缓存的生命周期(缓存什么时候过时),缓存的范围,清除缓存的方法(如果有的话),缓存的内容,如果默认情况下,缓存处于打开状态,如何打开/关闭缓存以及任何有用的信息。

我尝试在另一个问题中找到此信息,但找不到任何完整的答案。答案也分布在Hibernate文档中,但我也很难在那里找到它们。

我打算自己回答这个问题作为一个社区维基来推动这个问题,但我仍然不知道所有的答案,所以会有一些漏洞要填补。

2 个答案:

答案 0 :(得分:20)

隔离级别缓存

摘要:此缓存有时并不真正称为缓存。但是,为了实现某些隔离级别,数据库本身可能会缓存一些查询结果。

生命周期/范围:此缓存的范围限定为单个Session / EntityManager。生命周期与事务生命周期绑定。

清除缓存:除了开始新的交易之外我不知道

缓存的内容:查询和结果(如果隔离是可重复的读取或可序列化级别)

默认情况下为On 取决于来自数据库的默认隔离级别。默认情况下,MySQL提供可重复的读隔离,所以是的,默认情况下这是MySQL。

开启/关闭:可以在创建交易时指定。也可以通过更改数据库的默认值来更改。

有用信息:除了指定所需的隔离级别之外,Hibernate / JPA实际上无法控制此缓存的操作。

会话级别(第一级)缓存

摘要:此缓存是EntityManager / Session缓存。我相信这也是所谓的持久化背景。

生命周期/范围:此缓存的范围限定为单个Session / EntityManager。生命周期与事务生命周期绑定。

清除缓存:在EntityManager或Session上调用clear()会清除整个缓存。在会话上调用evict()会从缓存中清除单个对象。

缓存的内容:一切

默认开启:

开启/关闭:无法关闭

有用信息:只要调用flush(),此缓存就会与数据库合并。除非发生这种情况,否则其他事务将无法查看此缓存中的内容。保证flush()的最佳方法是提交事务。

二级缓存

摘要:这是可以启用的二级缓存(通常是尝试提高性能)。

生命周期/范围:我相信这是绑定到EntityManagerFactory / SessionFactory。自动驱逐此缓存取决于缓存策略。在只读策略中,数据永远不会被自动驱逐。在读写或nostrict读写策略中,数据将在会话关闭时被逐出。 不是100%确定。

清除缓存:您可以调用getCache().evict(class)来驱逐特定类,并getCache().evictAll()驱逐整个缓存。这些方法在EntityManagerFactory上。

缓存的内容:您明确配置应缓存哪些实体。

默认开启:

开启/关闭:在休眠配置中打开/关闭

实用信息:

查询缓存

摘要:查询缓存是一个存储查询,查询参数和结果的缓存。如果查询和查询参数相同,则可以预期结果相同。

生命周期/范围:我不知道此缓存中的数据何时被确定为陈旧。我相信范围是在EntityManagerFactory / SessionFactory级别。此外,Hibernate为每个表保留了“Hibernate的最后更新”时间戳列表。 Hibernate使用这些时间戳来确定查询结果是否过时并自动驱逐过时的查询。

清除缓存:SessionFactory上的evictQueries()方法可用于手动逐出查询缓存。

缓存的内容:查询及其结果

默认开启:

开启/关闭:在休眠配置中打开/关闭

有用信息:查询缓存仅缓存实体ID。它必须与二级缓存一起使用才能实现 true (无数据库访问)缓存。

答案 1 :(得分:4)

附加/更正:

  

(在2L缓存中)生命周期/范围:我相信这是绑定到EntityManagerFactory / SessionFactory。我不知道什么时候旧数据被清除。

此缓存被委托给专门的缓存提供程序,例如Infinispan或EhCache。因此,驱逐由您配置/请求,但由缓存提供程序执行。

  

(在2L缓存中)缓存的内容:一切

您需要明确告诉Hibernate要缓存哪些实体。

  

(查询缓存)摘要:这是另一个可以启用的二级缓存(通常是尝试提高性能)。

Query Cache是​​一个存储查询,查询参数和结果的缓存。如果查询和查询参数相同,则可以预期结果相同。当然,还有缓存失效技术,例如“如果此更新触及表X,则缓存无效”,这样缓存就不会失效。