【发布时间】:2018-07-12 10:04:01
【问题描述】:
我正在春季开发 API - JPA - Hibernate 应用程序。 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
}
这是我的弹簧配置
<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 的时间呈指数级增长。我没有预料到这一点,因为我正在逐一提交订单。 如果前 100 个订单大约需要 10 秒,那么第 900-1000 个订单需要超过 1 分钟。
现在如果我在控制器方法(bulkUpsert)的循环中调用 saveOrUpdateOrder 之后添加 entitymanager.clear(),api 变得很快。
虽然我很高兴问题得到解决,但我很困惑,因为我的理解与发生的事情不符。我期待当事务提交时,它会刷新所有的东西,一切都将重新开始下一次事务.
不是吗?
即使事务提交,实体是否仍保留在会话中?
【问题讨论】:
-
理论上你是对的。但是 Spring Boot 默认启用 Open EntityManager In View 模式,它为您提供 1 个实体管理器来处理整个请求。这也是为什么你会如此对待你所看到的行为。您可以禁用该模式(在您的
application.properties中将属性设置为false)以获得您期望的行为。但是,这可能会破坏应用程序的其他部分(在不知不觉中)依赖它。
标签: spring hibernate jpa entitymanager