我正在寻找一个简单、完整、简洁的缓存列表,您将在使用Hibernate编写JPA时遇到这些缓存。
特别是,我想知道每个缓存的生命周期(缓存何时失效),缓存的范围,清除缓存的方法(如果有),缓存的内容,缓存是否默认打开,如何打开/关闭它,以及任何有用的信息。
我试图在另一个问题中找到这个信息,但找不到任何完整的答案。答案也散布在Hibernate文档中,但我也很难在那里找到它们。
我计划以社区维基的身份来回答这个问题,但我仍然不知道所有的答案,所以会有一些漏洞需要填补。
发布于 2011-01-31 23:47:09
隔离级别缓存
摘要:此缓存有时并不真正称为缓存。但是,为了实现特定的隔离级别,数据库本身可能会缓存一些查询结果。
Lifecycle/Scope:此缓存的作用域为单个会话/实体管理器。生命周期绑定到事务生命周期。
清除缓存:我只知道启动一个新事务
缓存的内容:查询和结果(如果隔离处于可重复读取或可序列化级别)
默认情况下打开:取决于来自数据库的默认隔离级别。默认情况下,MySQL附带了可重复的读隔离,所以是的,对于MySQL,这是默认开启的。
打开/关闭:可以在创建事务时指定。也可以通过更改数据库上的默认值来更改。
有用信息: Hibernate/JPA除了指定所需的隔离级别外,实际上对此缓存的操作没有任何控制。
会话级(1级)缓存
摘要:此缓存是实体管理器/会话缓存。我相信这也是所谓的持久性上下文。
Lifecycle/Scope:此缓存的作用域为单个会话/实体管理器。生命周期绑定到事务生命周期。
清除缓存:在EntityManager或会话上调用clear()将清除整个缓存。在会话上调用evict()将从缓存中清除单个对象。
缓存内容:
默认打开:是
打开/关闭:无法关闭
有用信息:每当调用flush()时,此缓存都会与数据库合并。除非发生这种情况,否则其他事务将无法看到此缓存中的内容。保证flush()的最好方法是提交事务。
二级缓存
摘要:这是一个可以启用的二级缓存(通常是为了尝试和提高性能)。
Lifecycle/Scope:我相信这是绑定到EntityManagerFactory/会话工厂的。此缓存的自动逐出取决于缓存策略。在只读策略中,数据永远不会自动逐出。在读写或非严格读写策略中,当会话关闭时,数据将被逐出。对此并不是百分之百确定。
清除缓存:您可以调用getCache().evict(class)来清除特定的类,调用getCache().evictAll()来清除整个缓存。这些方法都在EntityManagerFactory上。
缓存内容:您可以显式地配置哪些实体应该被缓存。
默认开启: No
打开/关闭:在Hibernate配置中打开/关闭
有用信息:
查询缓存
摘要:查询缓存是存储查询、查询参数和结果的缓存。如果查询和查询参数相同,则可以预期结果相同。
Lifecycle/Scope:我不知道这个缓存中的数据何时被确定为陈旧。我相信范围是在EntityManagerFactory/SessionFactory级别。此外,Hibernate为每个表保留了一个“上次由Hibernate更新”的时间戳列表。Hibernate使用这些时间戳来确定查询结果是否过时,并自动驱逐过时的查询。
清除缓存: SessionFactory上的evictQueries()方法可用于手动清除查询缓存。
缓存的内容:查询及其结果
默认开启: No
打开/关闭:在Hibernate配置中打开/关闭
有用信息:查询缓存只缓存实体ID。它必须与二级缓存结合使用,才能实现真正的(无数据库访问)缓存。
发布于 2011-01-31 23:59:16
添加/更正:
(在2L缓存中)生命周期/作用域:我相信这是绑定到EntityManagerFactory/SessionFactory的。我不知道旧数据什么时候会被清除。
此高速缓存被委托给专门的高速缓存提供商,例如Infinispan或EhCache。因此,逐出是由您配置/请求的,但由缓存提供程序执行。
(在2L缓存中)缓存的内容:所有内容
您需要显式地告诉Hibernate您想要缓存哪些实体。
(查询缓存)摘要:这是另一个可以启用的二级缓存(通常是为了提高性能)。
查询缓存是存储查询、查询参数和结果的缓存。如果查询和查询参数相同,则可以预期结果相同。当然,还有一些缓存失效技术,比如“如果此更新触及了表X,则使缓存失效”,这样缓存就不会变得陈旧。
https://stackoverflow.com/questions/4852685
复制相似问题