简体   繁体   English

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

[英]Spring - Hibernate improve transaction performance with FlushMode

I'm trying to improve the performances of my asynk transactional method. 我正在努力提高我的asynk事务方法的性能。

In this task I have to read almost 7500 record from a table, elaborate it, and insert/update a corresponding row in another table. 在这个任务中,我必须从表中读取近7500条记录,详细说明,并在另一个表中插入/更新相应的行。

I'm using spring data jpa with hibernate. 我正在使用spring数据jpa和hibernate。

In order to get a ScrollableResults I inject the EntityManager into my service. 为了获得ScrollableResults我将EntityManager注入我的服务。

Here how I get my ScrollableResult object: 这是我如何得到我的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
}

Cycling on result take about 60 seconds. 循环结果大约需要60秒。

And here the bottleneck. 而这里的瓶颈。 If inside my loop I execute a simple query: 如果在我的循环中我执行一个简单的查询:

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

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

The execution time become x10 slower.. and takes about 600s. 执行时间变得慢了x10 ..并且需要大约600秒。

I've tried to modify a parameter of my Session or of my EntityManager : session.setFlushMode(FlushModeType.COMMIT); 我试图修改Session或我的EntityManager的参数: session.setFlushMode(FlushModeType.COMMIT); em.setFlushMode(FlushModeType.COMMIT);

It increase the performance and removing the manual flush() method the work is done in 40s!!! 它提高了性能并删除了手动flush()方法,工作在40年代完成!

So my questions are: 所以我的问题是:

  • What is the difference of call setFlushMode on session or on enityManager ? 是什么叫的差异setFlushModesession上或enityManager
  • Why setFlushMode(FlushModeType.COMMIT); 为什么setFlushMode(FlushModeType.COMMIT); increase in that way performance, and I cannot have same performance only by manually flushing entityManager? 以这种方式增加性能,我只能通过手动刷新entityManager来获得相同的性能?

The problem is that the default flush mode is FlushModeType.AUTO . 问题是默认刷新模式是FlushModeType.AUTO In auto flush mode, Hibernate will flush before each query (only queries, not find operations). 在自动刷新模式下,Hibernate将在每次查询之前刷新(仅查询,而不是查找操作)。 This means that in your above example, by default, Hibernate is flushing each time you call getSingleResult() . 这意味着在上面的示例中,默认情况下,每次调用getSingleResult()时,Hibernate都会刷新。 The reason it does this is because it's possible that the changes you have made would affect the results of your query and so Hibernate wants your query to be as accurate as possible and flushes first. 这样做的原因是因为您所做的更改可能会影响查询结果,因此Hibernate希望您的查询尽可能准确并首先刷新。

You don't see the performance hit in your first example because you are only issuing one query and scrolling through it. 您没有在第一个示例中看到性能损失,因为您只发出一个查询并滚动它。 The best solution I have found is the one you mentioned which is just to set the flush mode to COMMIT . 我找到的最好的解决方案是你提到的只是将刷新模式设置为COMMIT There should be no difference between calling setFlushMode on the Session or the EntityManager . SessionEntityManager上调用setFlushMode之间应该没有区别。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM