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

我正在努力提高我的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年代完成!

所以我的问题是:

>在session或enityManager上调用setFlushMode有什么区别?
>为什么选择setFlushMode(FlushModeType.COMMIT);以这种方式增加性能,我只能通过手动刷新entityManager来获得相同的性能?

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

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

转载注明原文:java – Spring – Hibernate使用FlushMode提高事务性能 - 代码日志