春季 - 冬眠通过Flushmode改善了交易性能



我正在尝试改善Asynk交易方法的性能。

在此任务中,我必须从表中读取几乎7500个记录,详细说明,然后在另一个表中插入/更新相应的行。

我正在使用Hibernate的Spring Data JPA。

为了使ScrollableResults i将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();     
 }

执行时间变慢。..

大约需要600。

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

它增加了性能并删除手动flush()方法该工作是在40年代完成的!!!

所以我的问题是:

  • sessionenityManager上的setFlushMode有什么区别?
  • 为什么setFlushMode(FlushModeType.COMMIT);以这种方式提高性能,而我只能通过手动冲洗实体才能具有相同的性能?

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

您没有看到第一个示例中的性能打击,因为您只发出一个查询并滚动浏览它。我发现的最好的解决方案是您提到的,它只是将冲洗模式设置为COMMIT。在SessionEntityManager上调用setFlushMode之间没有区别。

最新更新