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

 手机用户2702938842_284 发布于 2023-01-30 19:45

我正在努力提高我的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来获得相同的性能?

Pace.. 5

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

您没有在第一个示例中看到性能损失,因为您只发出一个查询并滚动浏览它.我找到的最好的解决方案是你提到的只是将刷新模式设置为COMMIT.应该有打电话没有任何区别setFlushModeSessionEntityManager.

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

    您没有在第一个示例中看到性能损失,因为您只发出一个查询并滚动浏览它.我找到的最好的解决方案是你提到的只是将刷新模式设置为COMMIT.应该有打电话没有任何区别setFlushModeSessionEntityManager.

    2023-01-30 19:48 回答
撰写答案
今天,你开发时遇到什么问题呢?
立即提问
热门标签
PHP1.CN | 中国最专业的PHP中文社区 | PNG素材下载 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有