休眠:批处理大小?二级缓存?

Posted

技术标签:

【中文标题】休眠:批处理大小?二级缓存?【英文标题】:Hibernate: batch_size? Second Level Cache? 【发布时间】:2010-11-22 16:58:58 【问题描述】:

我有一个 Hibernate 域对象,它被应用程序的不同部分加载。有时延迟加载每个关联是有利的,而其他关联则最好在一个连接中加载整个事物。作为一个有希望的妥协,我发现:

使用批量获取,如果访问一个代理,Hibernate 可以加载多个未初始化的代理。批量抓取是对惰性选择抓取策略的优化。

hibernate.default_batch_fetch_size:

使用批量获取,Hibernate 可以加载多个未初始化的代理 如果访问一个代理。批量获取是对 惰性选择获取策略。

我也看到了:

hibernate.jdbc.fetch_size:

一个非零值决定了 JDBC 提取大小(调用 Statement.setFetchSize())。

Hibernate 是否足够聪明,可以在批量获取时查看二级缓存?即为对关联的初始调用进行一次获取,然后下一个 X 调用命中缓存?这样,我可以进行我想要的延迟加载,但也可以经常访问缓存以进行更多类似批量的事务。

如果集合的全部内容已经包含在缓存中,它还会在访问集合时执行获取查询吗?

谢谢。

【问题讨论】:

现在我也想知道答案。 标记我的问题 :-) 【参考方案1】:

我今天做了很多研究,并且能够找到对我自己问题的回答。我正在查看 Hibernate 代码,流程如下所示:

集合初始化了吗?

没有?做一个batch fetch(batch-fetch得到的item放到缓存中) 是吗?在缓存中查找特定项目,如果没有,请执行批量提取。

因此,如果在缓存中找到您要查找的集合中的项目,则不会发生批量提取。如果在二级缓存中未找到该项目,则进行批量获取,但无论批量项目是否在缓存中,它都会获取批量项目。


----- 示例 1 -----

善:

(集合中的三个项目 - 批量大小为 3) 第一次去:

collection.getItem(0) - 无缓存 |批量获取 3 个项目 collection.getItem(1) - 通过批量获取加载 collection.getItem(2) - 通过批量获取加载

现在,在其他地方,以后的时间:

collection.getItem(0) - 缓存命中 collection.getItem(1) - 缓存命中 collection.getItem(2) - 缓存命中

----- 示例 2 -----

坏人:

(一个集合中的三个项目 - 批量大小为 3)

在这种情况下,索引 0 处的项目已从缓存中删除,因为可能缓存已满并且该项目已被删除,或者该项目已过时或空闲。

collection.getItem(0) - 不在缓存中,批次 3 也是如此(选择 * where id in (?, ?, ?)) collection.getItem(1) - 已在缓存中(无论如何替换为批量提取) collection.getItem(2) - 已在缓存中(无论如何替换为批量提取)

因此,这里的权衡是由于批处理,您将有更少的 SQL 调用,但您会更频繁地错过缓存。有一个工单可以让批处理在二级缓存中查找,然后再发送到数据库。

http://opensource.atlassian.com/projects/hibernate/browse/HHH-1775

投票!

【讨论】:

以上是关于休眠:批处理大小?二级缓存?的主要内容,如果未能解决你的问题,请参考以下文章

何时以及如何使用休眠二级缓存?

清除休眠二级缓存

休眠:无法启用二级缓存

共享 nHibernate 和 hibernate 二级缓存

hibernate二级缓存很慢

谁给我解释一下一级缓存和二级缓存啊~