【问题标题】:Caching (Ehcache) - Hibernate 2nd level cache and Spring缓存 (Ehcache) - Hibernate 二级缓存和 Spring
【发布时间】:2012-12-12 03:28:32
【问题描述】:

在我的 Web 应用程序(Spring 3.1、Hibernate 4)中,我将 Ehcache 用于 Hibernate 二级缓存和 Spring @Cache。我想知道,Hibernate Cache和Spring Cache在哪里使用?

例如,我有几个域类(在数据库中查看)用作屏幕上的查找值。我可以使用 Hibernate 二级缓存以及 Spring @Cache 缓存它们。

因此,在我的服务层中,如果我使用 Spring @Cache 缓存这些域对象,一旦缓存,我将接收到这些对象而根本不会触及持久层(休眠 HQL 查询)。这是正确的方法吗?

【问题讨论】:

    标签: spring hibernate caching ehcache


    【解决方案1】:

    取决于您的层架构。

    假设您有三个服务(或同一服务中的三个方法),它们都返回Customer 实体的集合,即域对象。如果您在服务层缓存,则单个数据库记录的相同表示很可能会多次存在于缓存中。它们是具有基本相同信息的多个对象。为什么?因为Service.getWhateverCustomers(String)Service.getWhateverCustomers(String, Integer)的结果存储在两个不同的缓存键下。

    另一方面,如果您使用 JPA @Cachable 注释在实体级别缓存,则无论您从哪个服务或服务方法调用实际检索实体的代码,都会缓存您的 Customer 实体。当然,有关 JPA 提供者何时可以/确实缓存实体的规则适用。如果您不熟悉它们,请阅读它们。

    希望这能让您了解要遵循的路径。如果您有更多问题,请发布后续 cmets,我将编辑此答案。

    【讨论】:

    • 我同意你给出的例子。我的情况略有不同。我在服务层有一个方法来获取所有查找值。所以,我在服务层方法上定义了@cache。 (我相信,它具有更好的性能,因为根本不涉及持久层)。我的一些实体使用休眠进行缓存,而其他实体(如查找值)则由 spring 缓存。这是正确的方法吗?还是我应该通过休眠来管理所有内容 - 忽略很少的性能提升?
    • @Ketan,“我相信,它有更好的性能” - 这是错误的方法。您应该衡量而不是相信或猜测。正如瑞安斯图尔特所说,只有当您遇到无法解决的性能问题时才考虑缓存。除此之外,我没有任何个人喜好。但是,在单层上缓存(无论是持久性还是服务)在架构上当然更干净。
    【解决方案2】:

    正确的做法是:

    1. 问问自己是否需要处理缓存的复杂性。您的应用是否未能达到要求?
    2. 仅当对上一个问题的回答为“是”时,才能分析您的应用以找出性能问题所在。
    3. 确定解决步骤 2 中确定的性能问题的适当方法。它可能涉及也可能不涉及缓存以防止代价高昂的操作。如果它确实涉及缓存,那么应该非常清楚地缓存在哪里以及使用哪个缓存,因为您会确切地知道您要防止发生什么。

    这个故事的寓意是你不缓存,因为它很酷。您缓存性能。还有你only optimize code when it's proven necessary

    【讨论】: