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

时间:2014-01-28 10:58:31

标签: java spring hibernate entitymanager spring-data-jpa

我正在努力改善我的asynk交易方法的表现。

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

我正在使用spring数据jpa和hibernate。

为了获得ScrollableResults我将EntityManager注入我的服务。

这是我如何获取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();     
 }

执行时间变得慢了x10 ..并且需要大约600秒。

我尝试修改Session或我的EntityManager的参数:session.setFlushMode(FlushModeType.COMMIT); em.setFlushMode(FlushModeType.COMMIT);

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

所以我的问题是:

  • setFlushModesession上致电enityManager有何不同?
  • 为什么setFlushMode(FlushModeType.COMMIT);以这种方式增加性能,而且我只能通过手动刷新entityManager来获得相同的性能?

1 个答案:

答案 0 :(得分:5)

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

您在第一个示例中没有看到性能影响,因为您只发出一个查询并滚动浏览它。我找到的最好的解决方案是你提到的只是将刷新模式设置为COMMIT的解决方案。在setFlushModeSession上调用EntityManager之间应该没有区别。

相关问题