Hibernate是否支持同时获取数据?

时间:2015-08-21 16:19:27

标签: java hibernate jpa orm concurrency

我理解这是一个难题,因为它不仅依赖于休眠,而且还依赖于我们使用它的特定方式。 我们在我们的应用程序中使用hibernate 4,可能是以错误的方式,但就是这样。

因此,我们加载一个完整的类层次结构,在一个大语句中加入子类表,并获得150K行的顺序,我们将其转换为对象。

由于对象有很多要设置的字段(~100),我们希望并行化循环结果集并获取各行的循环。这可能在Hibernate中吗? Hibernate是否已收到来自DB的所有结果并可以使用数据来保存对象,因此我们可以使用多线程来加速获取大型结果集?

这是否有意义或更好地更改数据结构和映射以摆脱多表连接?

实际上,加载150K这些对象需要一分钟或0.3毫秒/实体。我们有更简单的表,有更多的条目,我们加载一个数量级更快,0.02 ms /实体。我们不会在初始化阶段之后加载其他实体,整个数据库需要5分钟以上。

如果我们通过将类层次结构暴露给数据库并切换到基于组合的数据结构来删除连接,我们可能会以多个表加载为代价而不是一个具有这些加载的连接,从而获得更简单的表加载而不是复杂的连接合二为一。

但问题仍然存在:如果我们要加载这么多行,并且在填写每个对象的字段时要调用许多setter,这可以并行完成吗?

2 个答案:

答案 0 :(得分:2)

不,Hibernate中没有这样的东西。

但是,如果您提到的数据集彼此独立,则可以同时在不同的线程中加载不同会话(事务)中的每个数据集(每个数据集一个线程和会话)。然后从所有线程中获取结果。

此方法的另一个好处是您还可以并行化数据集的查询执行。

答案 1 :(得分:0)

如果你想将所有实体提取到二级缓存中,那么你确实可能想要获取所有数据,但我认为这不是一个好主意。

我认为你应该只缓存访问量最大的数据,而不是整个条目。这样,缓存将需要更少的空间,您不需要一次获取整个结果集。

如果你真的想要获取所有数据,我建议采用另一种方法。

您可以使用Java并发来并行化多个线程上的fetch,因此您需要设置一个EexcutorService,它接受Callable并尝试批量获取条目。

如果您有N个处理器,则可以使用N个工作线程。您将根实体ID间隔除以N,这样您就可以获得N个子间隔。每个工作线程将处理一个这样的间隔并批量加载数据。这样你就不必同步N个工作线程,以避免两次加载相同的数据。因为ID通常是索引的,所以按根实体ID对条目进行排序并从上次处理的ID开始获取批次可能会显着加快加载速度。

相关问题