【问题标题】:Hibernate 2nd level cache in a Grails appGrails 应用程序中的休眠二级缓存
【发布时间】:2012-03-09 20:03:54
【问题描述】:

第一部分

在 Grails 应用程序中,我了解到您通过添加启用每个域类的二级缓存

static mapping {
  cache true
}

默认情况下,二级缓存仅在调用get() 时使用,但也可以通过在查询中添加cache true 用于条件查询和动态查找器。

但是,我仍然不确定我是否了解查询缓存的工作原理。我的最佳猜测是:

  • 每个域类都有单独的查询缓存,例如一个给书,另一个给作者
  • 在执行像Author.findByName('bob', [cache: true]) 这样的查询之前,会根据域类(作者)、查询(findByName)和查询参数('bob')计算缓存键。如果在作者查询缓存中找到该键,则返回缓存结果而不是执行查询
  • 只要作者被保存、删除或更新,作者查询缓存就会被刷新

这似乎是合理的,直到我们考虑到返回 Book 实例的查询可能会连接到 Author 表。在这种情况下,有必要在保存、删除或更新作者时同时刷新 Book 和 Author 查询缓存。这让我怀疑可能只有一个查询缓存,并且在保存任何缓存的域类时都会清除它?

第二部分

在 Grails 文档中提到

除了使用 Hibernate 的二级缓存来缓存实例的能力之外,您还可以缓存对象的集合(关联)。

例如:

class Author {    

  static hasMany = [books: Book]

  static mapping = { 
    cache true        // Author uses the 2nd level cache
    books cache: true // associated books use the 2nd level cache
  } 
}

class Book {
  static belongsTo = [author: Author]

  static mapping = {
    cache true // Book uses the 2nd level cache
  }
}

上面的配置是否有意义,即如果作者和书籍本身使用二级缓存,那么让作者-书籍关联也使用二级缓存有什么好处吗?

第三部分

最后,我阅读了this advice 关于使用二级查询缓存的信息,这表明它应该只用于不经常更改的域类。是否存在不应该为get() 操作启用二级缓存的情况,即不将以下内容添加到域类的任何原因

static mapping = {
  cache true // Book uses the 2nd level cache
}

【问题讨论】:

    标签: hibernate caching grails grails-orm


    【解决方案1】:

    第 1 部分:

    Hibernate 做了正确的事。查询缓存不是每个实体。有一个查询缓存区域,由所有查询共享,除非您为查询设置特定区域。每次更新表时,都会更新其在时间戳缓存中的时间戳。每次执行查询时,都会将查询搜索的每个表的时间戳与缓存结果的时间戳进行比较。当然,只有当它的时间戳比所有表的时间戳都更新时才会返回缓存的结果。

    第 2 部分:

    是的,这是有道理的。作者的缓存记得 ID 为 456 的作者的名字是“foo”,出生日期是 1975/07/19。只有存储在 author 表中的数据会被记住。因此,缓存关联也很有用:Hibernate 不会在调用author.getBooks() 时进行额外的查询来获取作者的书籍集,而是会从其缓存中获取作者的书籍 ID,然后加载每本书来自二级缓存。不过,请确保缓存书籍。

    第三部分:

    我可以想象几个原因:

    • 实体如此之多,而且它们的变化如此之大,以至于缓存命中的数量会非常少,而且二级缓存处理实际上会比没有缓存的解决方案消耗更多的时间和内存
    • 应用集群化,分布式二级缓存成本和复杂度太高,收益低
    • 其他非休眠应用程序写入同一个数据库,缓存因此有很大的风险返回陈旧数据,这是不可接受的
    • 没有二级缓存一切都很好,没有理由让应用程序变得比现在更复杂。

    【讨论】:

    • 很好的答案,非常感谢。你能证实/反驳我的理论,即查询的缓存键是从查询及其参数派生的吗?
    • 查看休眠文档more info on how caching works
    猜你喜欢
    • 2019-04-08
    • 2010-10-20
    • 1970-01-01
    • 2010-10-29
    • 1970-01-01
    • 2019-04-02
    • 2017-07-05
    • 2011-07-08
    相关资源
    最近更新 更多