【问题标题】:Advanced knowledge on Hibernate second-level cacheHibernate二级缓存进阶知识
【发布时间】:2023-06-09 23:51:01
【问题描述】:

我相信通过明智地使用 Hibernate 的二级缓存可以很好地提高我的应用程序的性能,为此我已经开始从 Internet 和 Hibernate 课程中学习它。 尽管对二级缓存及其工作方式有很好的解释,但我的目标是弄清楚事情是如何工作的,从我没有找到的具体问题开始,因此我一般会问一些关于 Hibernate 缓存的问题尤其是二级缓存。

答题注意事项:

A.即使有些问题看起来很明显或无关紧要,我也将不胜感激。
B. 如果问题取决于缓存提供者,我想听听有关 Ehcache 的答案
C. 欢迎回答部分不确定性问题

问题:

  1. 一旦配置了二级缓存,一级缓存会被禁用吗?如果不是,那么在尝试获取实体时如何发生事件过程,首先命中哪个缓存级别?

  2. 查询缓存是将查询文本保存为 HQL 还是原生 SQL?

  3. 通过 JPA 和 Hibernate 直接使用 Hibernate 时,二级缓存的工作方式是否相同?

  4. 我了解查询缓存通过使用位于查询缓存中的 ID 访问二级缓存来参与二级缓存。如果某些 ID 由于某种原因不再位于二级缓存中,会再次获取所有实体,还是仅获取不存在的部分?

  5. 关于同步——通过在某个事务中更新存储在二级缓存中的实体——如果有的话,何时会在二级缓存中更新实体?将欣赏更多详细信息,了解此行为如何影响 2 级缓存和查询缓存。


    谢谢!

【问题讨论】:

    标签: java hibernate ehcache second-level-cache query-cache


    【解决方案1】:
    1. 没有。一级缓存继续使用。唯一的区别是实体可能来自二级缓存而不是数据库,并且它们被保存到除了数据库之外的二级缓存。

    2. 不像 HQL,因为条件查询也可以被缓存。我认为使用了 SQL。但这不是必须缓存的唯一内容:查询的参数也被缓存。不过你不应该关心这个:缓存会缓存你的查询,无论它使用什么都无关紧要,只要执行两次相同的查询会命中缓存,而执行非缓存查询则不会。

    3. 是的。

    4. 只有那些不在缓存中的,AFAIK。对其进行测试并查看执行了哪些 SQL 查询。

    5. 这取决于cache concurrency strategy 和缓存的功能。二级缓存主要在实体为只读或几乎只读时有用。

    【讨论】:

    • 相对于 1 号答案 - 如果我会尝试获取在 1 级和 2 级缓存中都使用的实体,过程将是:在 1 级缓存中搜索实体,然后在二级缓存中搜索实体,因为没有实体 - 将实体添加到一级和二级缓存中。我的说法是真的吗?
    【解决方案2】:

    更多细节:

    [4]。查询缓存与更新时间戳缓存结合使用。如果插入/删除/更新了实体类型的任何实例,则对该实体类型的所有查询都将无效。因此,如果任何实体消失了,该实体类型的所有查询都将失效,因此将重新执行查询。查询缓存以这种方式工作,因为 Hibernate 很难确定某个特定实例是否被任何查询触及,因此它采用了一种安全但不太理想的方法。因此,查询缓存可能只在大多数只读场景中提供性能提升。

    [5]。正常情况下,二级缓存在事务的afterCompletion()事务同步回调中​​更新。

    【讨论】: