代码之家  ›  专栏  ›  技术社区  ›  Rips

spring jpa hibernate-api中的重复事务使其变慢

  •  0
  • Rips  · 技术社区  · 6 年前

    我正在spring-jpa-hibernate应用程序中开发一个api。 api接收需要逐个持久化的订单列表。

    控制器方法如下

    bulkUpsert(@RequestBody Orders orders){
      for(Order order:orders.getOrders()){
           saveOrUpdateOrder(order);
      }
    }
    

    服务方式如下

    @Transactional
    saveOrUpdateOrder(Order order){
       //do processing and call dao methods to save/update
    }
    

    这是我的spring配置

    <bean id="transactionManager"
          class="org.springframework.orm.jpa.JpaTransactionManager"
          p:entityManagerFactory-ref="entityManagerFactory">
        <property name="defaultTimeout" value="${jdbc.defaultTransactionTimeout}"/>
    </bean>
    <tx:annotation-driven transaction-manager="transactionManager"/>
    

    Web XML:

     <filter>
        <filter-name>OpenEntityManagerInViewFilter</filter-name>
        <filter-class>org.springframework.orm.jpa.support.OpenEntityManagerInViewFilter</filter-class>
      </filter>
    

    现在我注意到的问题是,随着传递的订单数量的不断增加,完成api的时间呈指数增长,我并没有预料到这一点,因为我正在一个接一个地提交订单。 如果前100个订单需要10秒左右,那么第900-1000个订单需要1分钟以上。

    现在,如果我在控制器方法(bulkupsert)的循环中调用saveorupdateorder之后添加entitymanager.clear(),api就会变得很快。

    虽然我很高兴这个问题得到了解决,但我感到困惑,因为我的理解与已经发生的事情不符。我原以为当事务提交时,它将刷新所有的东西,并且下一个事务的所有内容都将重新开始。

    不是吗?

    即使在事务提交时,实体仍保留在会话中吗?

    1 回复  |  直到 6 年前
        1
  •  1
  •   M. Deinum    6 年前

    从理论上讲,您是正确的,但是由于spring boot默认启用 OpenEntityManagerInViewInterceptor 使 open entitymanager in view pattern 是的。这又会让你找到一个 EntityManager 根据要求。

    这解释了你所看到的行为,因为你希望得到一个新的和新鲜的 实体管理器 每个交易,但是预先注册的 实体管理器 被重复使用。

    您可以通过禁用 OpenEntityManager视图拦截器 是的。通过设置 spring.jpa.open-in-view false application.properties 文件。然而,这可能会导致其他代码出现问题,这些代码可能在不知不觉中依赖于open entitymanager的视图行为。