Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/hibernate/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Spring JPA hibernate-API中的重复事务使其速度变慢_Spring_Hibernate_Jpa_Entitymanager - Fatal编程技术网

Spring JPA hibernate-API中的重复事务使其速度变慢

Spring JPA hibernate-API中的重复事务使其速度变慢,spring,hibernate,jpa,entitymanager,Spring,Hibernate,Jpa,Entitymanager,我正在spring-JPA-Hibernate应用程序中开发一个API。 API接收需要逐个持久化的订单列表 控制器方法如下所示 bulkUpsert(@RequestBody Orders orders){ for(Order order:orders.getOrders()){ saveOrUpdateOrder(order); } } 服务方法如下 @Transactional saveOrUpdateOrder(Order order){ //do proc

我正在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>

OpenEntityManager视图过滤器
org.springframework.orm.jpa.support.OpenEntityManagerInViewFilter
现在我观察到的问题是,随着通过的订单数量不断增加,完成API的时间呈指数级增长。我没有预料到这一点,因为我正在一个接一个地提交订单。 如果前100个订单需要10秒左右,那么第900-1000个订单需要1分钟以上

现在,如果我在控制器方法(bulkUpsert)的循环中调用saveOrUpdateOrder之后添加entitymanager.clear(),api就会变得非常快速

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

不是吗


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

理论上您是正确的,但是,由于Spring Boot默认启用了,这将启用。这反过来会导致每个请求都有一个
EntityManager

这解释了您所看到的行为,因为您希望在每个事务中获得一个新的
EntityManager
,但预注册的
EntityManager
被重新使用


您可以通过禁用OpenEntityManagerViewInterceptor来解决此问题。通过将
application.properties
文件中的
spring.jpa.openin-view
设置为
false
来完成此操作。但是,这可能会导致其他代码出现问题,这些代码可能在不知不觉中依赖于OpenEntityManager的视图行为

理论上你是对的。然而,SpringBoot默认启用OpenEntityManager-In-View模式,该模式为整个请求处理提供1个EntityManager。这也是为什么你会这么做,你看到的行为。您可以禁用该模式(在
应用程序.properties
中将属性设置为
false
)以获得预期的行为。然而,这可能会破坏你的应用程序中(不知不觉地)依赖它的其他部分。我也在想,Required_new应该解决这个问题,但它没有。它和以前一样慢。我的坏。这并不能解决问题,因为单一的entitymanager仍然存在。您将有多个事务,但仍然只有一个entitymanager。我已经从我的答案中删除了这一点。所以我的问题是,即使只有一个entitymanager,为什么它会减慢API速度。如果我检查堆空间,它从来不会随着订单数量的增加而呈指数增长……或者它只是影响hibernate?这就是ORM的工作方式。这是因为有一个实体管理器,它会减慢速度。一级缓存(EntityManager)中的每个对象都会进行脏检查,它会对数据库的每个
刷新或查询进行脏检查。当您向单个entitymanager添加越来越多的实体时,速度会越来越慢。现在,当您调用
clear()
时,您基本上会从entitymanager中删除所有内容,无需进行任何检查。这就是为什么它这么快。我原以为它会在事务提交时删除所有内容,因为它会刷新所有内容并同步数据库?