当前位置: 首页 > 面试题库 >

Grails应用程序中的Hibernate 2级缓存

吴宏扬
2023-03-14
问题内容

第一部分

在Grails应用程序中,我了解到您可以通过添加以下方式为每个域类启用二级缓存

static mapping {
  cache true
}

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

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

  • 每个域类都有单独的查询缓存,例如一个用于Book,另一个用于Author
  • Author.findByName('bob', [cache: true])执行类似的查询之前,将根据域类(Author),查询(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
  }
}

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

第三部分

最后,我读过这个建议有关使用2级查询缓存,这表明它应该只被用于不频繁变化的领域类。是否有任何情况下不应为get()操作启用二级缓存,即为什么不将以下内容添加到域类的任何原因?

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

问题答案:

第1部分:

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

第2部分:

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

第3部分:

我可以想象几个原因:

  • 实体太多,而且它们变化如此之大,以至于高速缓存命中的数量将非常低,并且与没有高速缓存的解决方案相比,二级高速缓存处理实际上将消耗更多的时间和内存。
  • 应用程序是集群的,并且分布式二级缓存的成本和复杂性过高,导致收益较低
  • 其他非hibernate应用程序写入同一数据库,因此缓存具有返回陈旧数据的巨大风险,这是不可接受的
  • 如果没有二级缓存,一切都会很好地进行,并且没有理由使应用程序比原来的更加复杂。


 类似资料:
  • 我的情况是,我有Grails 2.1.2应用程序,并希望引入使用缓存插件和cache-ehcache插件作为实现的方法级缓存。 我的缓存配置为在内存中,如下所示: 我有一个像这样的方法,它只接受int参数,所以密钥生成不是问题: 我的问题是,当调用这个方法时,我得到了一个< code > Java . lang . out of memory error:Java heap space 异常。原因

  • 好的,我决定在框架grails中试试。按照手册安装了。创建一个测试项目: 运行测试项目: 没关系。 今天,Ubuntu提供了安装更新,更新包java-8-oracle-Inster。执行此更新命令后 结果: 我很感激你的帮助。

  • 更新我的Android应用程序的www文件夹(使用Cordova 3.6.3)时,该应用程序会显示我的www的旧缓存版本。 如果我清除应用程序数据(来自Android- 当应用程序更新时(或每次应用程序启动时),如何强制应用程序清除缓存?

  • 主要内容:什么是应用程序缓存(Application Cache)?,浏览器支持,HTML5 Cache Manifest 实例,实例,Cache Manifest 基础,Manifest 文件,更新缓存,实例 - 完整的 Manifest 文件,关于应用程序缓存的说明使用 HTML5,通过创建 cache manifest 文件,可以轻松地创建 web 应用的离线版本。 注意:manifest 的技术已被 web 标准废弃,不再推荐使用此功能。 什么是应用程序缓存(Application Ca

  • 使用 HTML5,通过创建 cache manifest 文件,可以轻松地创建 web 应用的离线版本。 什么是应用程序缓存(Application Cache)? HTML5 引入了应用程序缓存,这意味着 web 应用可进行缓存,并可在没有因特网连接时进行访问。 应用程序缓存为应用带来三个优势: 离线浏览 - 用户可在应用离线时使用它们 速度 - 已缓存资源加载得更快 减少服务器负载 - 浏览器

  • 问题内容: Tomcat 5.5.x和6.0.x Grails 1.6.x Java 1.6.x OS CentOS 5.x(64位) VPS服务器,内存为384M JAVA_OPTS:尝试了许多组合-包括以下内容 出口JAVA_OPTS =’-Xms128M -Xmx512M -XX:MaxPermSize = 1024m’ 导出JAVA_OPTS =’-server -Xms128M -Xmx