gpt4 book ai didi

java - Spring - Hibernate 使用 FlushMode 提高事务性能

转载 作者:搜寻专家 更新时间:2023-11-01 02:26:33 25 4
gpt4 key购买 nike

我正在努力提高异步事务方法的性能。

在这个任务中,我必须从一个表中读取近 7500 条记录,对其进行详细说明,然后在另一个表中插入/更新相应的行。

我在 hibernate 中使用 spring data jpa。

为了获得 ScrollableResults,我将 EntityManager 注入(inject)到我的服务中。

这里是我如何获得我的 ScrollableResult 对象:

Session session = (Session) em.unwrap(Session.class);
ScrollableResults res = session.createQuery("from SourceTable s")
.setCacheMode(CacheMode.IGNORE)
.scroll(ScrollMode.FORWARD_ONLY);


while (res.next()){
.... // em.flush() called every 40 cycles
}

结果循环大约需要 60 秒。

这里是瓶颈。如果在我的循环中执行一个简单的查询:

query = em.createQuery("from DestTable d where d.item.id = :id", DestTable.class);

while (res.next()){
query.setParameter("id", myId).getSingleResult();
}

执行时间变慢了 10 倍......大约需要 600 秒。

我试图修改我的 SessionEntityManager 的参数:session.setFlushMode(FlushModeType.COMMIT);em.setFlushMode(FlushModeType.COMMIT);

它提高了性能并删除了手动 flush() 方法,工作在 40 秒内完成!!!

所以我的问题是:

  • sessionenityManager 上调用 setFlushMode 有什么区别?
  • 为什么 setFlushMode(FlushModeType.COMMIT); 以这种方式提高性能,而我不能仅通过手动刷新 entityManager 获得相同的性能?

最佳答案

问题是默认的刷新模式是 FlushModeType.AUTO。在自动刷新模式下,Hibernate 将在每次查询之前刷新(仅查询,不查找操作)。这意味着在您上面的示例中,默认情况下,每次您调用 getSingleResult() 时,Hibernate 都会刷新。它这样做的原因是因为您所做的更改可能会影响查询的结果,因此 Hibernate 希望您的查询尽可能准确并首先刷新。

您在第一个示例中看不到性能下降,因为您只发出一个查询并滚动浏览它。我找到的最佳解决方案是您提到的那个,它只是将刷新模式设置为 COMMIT。在 SessionEntityManager 上调用 setFlushMode 应该没有区别。

关于java - Spring - Hibernate 使用 FlushMode 提高事务性能,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21403726/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com