Hibernate + Spring中的缓存 - 一些问题

66
我正在使用Spring 3和Hibernate 3.6开发Web应用程序。目前,我试图了解Spring和Hibernate中的缓存机制如何工作。我找到了一些关于Hibernate缓存的资料和一些关于Spring的资料,现在我正在尝试将我的信息整合在一起。我仍然对这两个框架有一些疑问,如果有人能回答它们或告诉我这里列出的事实是否正确,我会很高兴。
大多数情况下,简短的回答(是/否)就足够了。我认为这个列表对于其他想了解Spring和Hibernate如何工作的人也很有用。
1) Hibernate支持以下缓存:1级缓存、2级缓存、查询缓存 2) Spring本身支持以下缓存方式:方法缓存
1级缓存 3) 1级缓存是每个Hibernate应用程序的一部分。 4) 1级缓存是为每个Hibernate会话创建的。 5) 1级缓存保存什么?对象还是只有其属性的值?查询及其结果?
2级缓存 6) 我发现:2级缓存在每个应用程序中只使用一次。这不是错误的吗?它不是在每个SessionFactory中使用一次吗?多个sessionfactorys = 多个2级缓存可能? 7) 2级缓存中保存什么:我认为只有属于一个记录的值,而不是对象本身。 8) 将一个记录的值存储在第二级缓存中时,是否可以将与之相关的值(从连接到外键的对象)一起存储? 9) 在第二级缓存中更新一个对象的值时,是否可以更新与之连接的对象在缓存中的值? 10) 当对象的值发生变化时,如何更新第二级缓存?刷新?我可以只更新缓存的一部分还是必须更新整个缓存? 11) 第二级缓存在哪些情况下有意义,在哪些情况下没有意义? 12) 缓存模式:每种缓存模式是否提供不同的缓存策略?例如,使用"read-only"缓存模式永远不需要进行数据库和缓存的同步?其他缓存模式是否提供同步?我认为同步必须由开发人员自己完成?
查询缓存 13) 查询缓存和第二级缓存有什么区别?在我看来:在查询缓存中,结果集被保存,但没有其值,只有其ID。当再次使用查询并且结果集仍然“正确”时,从第2级缓存中查询属于ID的值。 14) 对于查询缓存,必须使用第二级缓存吗? 15) 查询缓存在哪些情况下有意义,在哪些情况下没有意义?
Spring 16) Spring提供比方法缓存更多的缓存可能性吗? 17) 方法缓存与Hibernate缓存无关。 18) 但是:对于方法缓存,第2级缓存是必需的,例如Ehcache(也可由Hibernate使用) 19) 可以在没有数据库查询的情况下使用方法缓存吗?
混淆了 20) 如果将Ehcache用于Hibernate作为第2级缓存,并且将Ehcache用于Spring作为方法缓存,我可以使用相同的Ehcache实例吗?有没有可能混淆什么? 21) 当使用1级缓存和2级缓存时,它们是否会混淆?当查询数据库时,结果来自哪里,第1级还是第2
2个回答

82

Hibernate支持以下缓存:一级缓存、二级缓存和查询缓存。

是的。

Spring本身支持以下缓存功能:只有方法缓存。

Spring 3.1引入了基于方法注释的新缓存抽象。

一级缓存是每个Hibernate应用程序的一部分。

是的。

为每个Hibernate会话创建一级缓存。

是的,尽管您可以在任何时候手动清除它。

一级缓存保存什么?对象还是仅其属性的值?查询及其结果?

它是在会话生命周期中获取的所有对象的映射,如果第二次按ID加载相同的对象,则将从L1中加载。

我发现:二级缓存每个应用程序只使用一次。这不是假的吗?它不是每个sessionfactory使用一次吗? 多个sessionfactorys = 可能有多个二级缓存?

您是正确的,通常每个应用程序(数据库)只有一个session工厂,因此采用这种简便方式。

二级缓存中保存的内容:我认为只是属于一个记录的值,而不是对象本身。

与L1相同的东西,但它们的生命周期更长。 L2通常由一些工业级缓存支持,而L1只是一个映射(甚至不必是线程安全的)。它存储完整的实体,包括延迟加载的关系。

在将一个记录的值存储到二级缓存中时,是否可以将相关值(来自通过外键连接的对象)与之一起存储?

您不需要手动管理L2,它会自动发生。

Measure. In applications with frequently used queries, the Query Cache can significantly reduce database load and improve performance. However, for queries that are rarely used or have a high update frequency, the Query Cache may not be beneficial.

当你执行相同的查询多次,查询参数的范围较小(对于每组查询参数,都会创建一个新的查询缓存,其中所有记录的 ID 都是结果),这通常是一个难题。

Spring是否提供比方法缓存更多的缓存可能性?

不,Spring 更多地只是为您自己的代码提供了一种粘合剂。

方法缓存与 Hibernate 缓存没有关联。

Spring 与 Hibernate 没有关联,所以...

但是:对于方法缓存,需要第二级缓存,例如 ehcache(也可以被 Hibernate 使用)

L2 是 Hibernate 的概念。如果要缓存方法,则需要某些底层的缓存。让它成为 EhCache,无论如何。当然,它必须是线程安全的。

可以在没有数据库查询的情况下使用方法缓存吗?

Spring 与 Hibernate 无关。您可以缓存与数据库无关的计算。

如果将 ehcache 用于 Hibernate 的第二级缓存,并将其用于 Spring 的方法缓存,我可以使用相同的 ehcache 实例吗?有机会会混淆吗?

您可以使用与 Hibernate 相同的 CacheManager 和缓存配置以便于部署。只要缓存名称不重叠,它们是完全独立的,即使在同一个管理器中工作。

在使用第一级缓存和第二级缓存时,它们会混淆吗?在查询数据库时,结果从哪里来,第一级还是第二级缓存?第一级缓存是否与第二级缓存一起工作?

只要某些抽象未泄露,它们就可以正常工作 :-)。当按主键查询时,首先检查 L1(速度更快),然后检查 L2。

还有什么东西会因使用我提到的缓存而混淆吗? :-)

如上所述,抽象通常会泄漏。但是最糟糕的问题是当您更改数据库时,Hibernate不知道它。此外,在没有适当复制的情况下进行集群会令人头痛。而最大的问题是,很多时候不正确的缓存实际上会减慢应用程序的速度(查询缓存在这里是最危险的)。


你是一个友善的老师 :) - Ali Sohrabi
非常有用的信息,解释得很好!!!非常感谢 - Slevin
非常有用的信息,解释得很好!!!非常感谢 - undefined

2

我知道 - 这就是我所说的“方法缓存”。它是相同的。 - nano7

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接