Spring JPA hibernate - API 中的重复事务使其变慢
Spring JPA hibernate -Repeated transactions in the API making it slow
我正在 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"/>
网络xml:
<filter>
<filter-name>OpenEntityManagerInViewFilter</filter-name>
<filter-class>org.springframework.orm.jpa.support.OpenEntityManagerInViewFilter</filter-class>
</filter>
现在我观察到的问题是,随着通过的订单数量不断增加,完成 API 的时间呈指数增长 increasing.I 没想到会这样,因为我正在承诺订单一个接一个。
如果前 100 个订单需要大约 10 秒,那么第 900-1000 个订单需要超过 1 分钟。
现在,如果我在控制器方法 (bulkUpsert) 的循环中调用 saveOrUpdateOrder 之后添加 entitymanager.clear(),api 会变得很快。
尽管我很高兴问题得到解决,但我感到困惑,因为我的理解与 happened.I 的预期不符,即当事务提交时,它将刷新所有内容,一切都会重新开始用于下一笔交易。
不是吗?
即使提交了事务,实体是否仍保留在会话中?
理论上你是正确的,但是 Spring 默认情况下启动会启用 OpenEntityManagerInViewInterceptor
which enables the open entitymanager in view pattern。这反过来会导致每个请求一个 EntityManager
。
这解释了您看到的行为,因为您希望每笔交易获得新的 EntityManager
,但预注册的 EntityManager
被重新使用。
您可以通过禁用 OpenEntityManagerInViewInterceptor
来解决这个问题。通过在 application.properties
文件中将 spring.jpa.open-in-view
设置为 false
来执行此操作。但是,这可能会导致其他代码出现问题,这些代码可能在不知不觉中依赖于视图行为中的开放实体管理器。
我正在 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"/>
网络xml:
<filter>
<filter-name>OpenEntityManagerInViewFilter</filter-name>
<filter-class>org.springframework.orm.jpa.support.OpenEntityManagerInViewFilter</filter-class>
</filter>
现在我观察到的问题是,随着通过的订单数量不断增加,完成 API 的时间呈指数增长 increasing.I 没想到会这样,因为我正在承诺订单一个接一个。 如果前 100 个订单需要大约 10 秒,那么第 900-1000 个订单需要超过 1 分钟。
现在,如果我在控制器方法 (bulkUpsert) 的循环中调用 saveOrUpdateOrder 之后添加 entitymanager.clear(),api 会变得很快。
尽管我很高兴问题得到解决,但我感到困惑,因为我的理解与 happened.I 的预期不符,即当事务提交时,它将刷新所有内容,一切都会重新开始用于下一笔交易。
不是吗?
即使提交了事务,实体是否仍保留在会话中?
理论上你是正确的,但是 Spring 默认情况下启动会启用 OpenEntityManagerInViewInterceptor
which enables the open entitymanager in view pattern。这反过来会导致每个请求一个 EntityManager
。
这解释了您看到的行为,因为您希望每笔交易获得新的 EntityManager
,但预注册的 EntityManager
被重新使用。
您可以通过禁用 OpenEntityManagerInViewInterceptor
来解决这个问题。通过在 application.properties
文件中将 spring.jpa.open-in-view
设置为 false
来执行此操作。但是,这可能会导致其他代码出现问题,这些代码可能在不知不觉中依赖于视图行为中的开放实体管理器。