我正在使用 Spring Web Flow 来构建应用程序。我正在利用Flow Managed Persistence Context
因此实体管理器在流程执行期间保持打开状态,我可以访问延迟加载的属性(类似于OpenEntityManagerInViewFilter
or OpenSessionInViewFilter
对于 Spring MVC)。当我使用这个时,每次提交表单时,活动数据库连接数都会增加,如果我不使用FMPC,则打开连接数没有问题)。
我正在使用以下设置。
事务管理器:
@Bean
@Autowired
public JpaTransactionManager transactionManager(EntityManagerFactory entityManagerFactory) {
return new JpaTransactionManager(entityManagerFactory);
}
数据源:
@Bean
public DataSource dataSource() {
final BasicDataSource dataSource = new BasicDataSource();
dataSource.setDriverClassName(environment.getRequiredProperty(PROPERTY_DATABASE_DRIVER));
dataSource.setUrl(environment.getRequiredProperty(PROPERTY_DATABASE_URL));
dataSource.setUsername(environment.getProperty(PROPERTY_DATABASE_USERNAME, ""));
dataSource.setPassword(environment.getProperty(PROPERTY_DATABASE_PASSWORD, ""));
return dataSource;
}
实体管理器工厂:
@Bean
public LocalContainerEntityManagerFactoryBean entityManagerFactory() {
final LocalContainerEntityManagerFactoryBean factoryBean = new LocalContainerEntityManagerFactoryBean();
factoryBean.setDataSource(dataSource());
factoryBean.setPackagesToScan(environment.getRequiredProperty(PROPERTY_ENTITYMANAGER_PACKAGES_TO_SCAN));
final JpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter() {
{
setDatabase(Database.valueOf(environment.getRequiredProperty(PROPERTY_DATABASE_TYPE)));
setDatabasePlatform(environment.getRequiredProperty(PROPERTY_HIBERNATE_DIALECT));
}
};
factoryBean.setJpaVendorAdapter(vendorAdapter);
final Properties jpaProperties = new Properties();
jpaProperties.put(PROPERTY_HIBERNATE_FORMAT_SQL, environment.getRequiredProperty(PROPERTY_HIBERNATE_FORMAT_SQL));
jpaProperties.put(PROPERTY_HIBERNATE_NAMING_STRATEGY, environment.getRequiredProperty(PROPERTY_HIBERNATE_NAMING_STRATEGY));
jpaProperties.put(PROPERTY_HIBERNATE_SHOW_SQL, environment.getRequiredProperty(PROPERTY_HIBERNATE_SHOW_SQL));
jpaProperties.put(PROPERTY_HIBERNATE_HB2DDL_SQL, environment.getRequiredProperty(PROPERTY_HIBERNATE_HB2DDL_SQL));
factoryBean.setJpaProperties(jpaProperties);
return factoryBean;
}
JpaFlowExecutionListener:
@Bean
@Autowired
public JpaFlowExecutionListener jpaFlowExecutionListener(EntityManagerFactory entityManagerFactory, JpaTransactionManager transactionManager) {
return new JpaFlowExecutionListener(entityManagerFactory, transactionManager);
}
The BasicDataSource
has maxActive
set to 8默认情况下,当我达到 8 个活动连接时,页面就会挂起。为什么请求完成后连接没有关闭?我使用了 Chrome 调试工具(网络窗格)来确保没有 AJAX 请求运行或任何其他内容,我的页面提交(HTTP POST)触发 301 重定向,然后给我一个新的 HTTP GET 并导致状态200,一切都好。
从一个页面转到下一个页面时,会调用一个服务层,但正如您从我的 bean 中看到的,我正在使用JpaTransactionManager
SWF 文档说明如下:
- 注意:默认情况下,除最终提交之外的所有数据访问都是非事务性的。但是,如果底层 JPA 事务管理器支持的话,流程可以在只读系统事务上下文中的对话期间调用事务服务层来获取对象。例如,当与 Hibernate JPA 提供程序一起使用时,Spring 的 JPA TransactionManager 确实支持这一点。在这种情况下,Spring 将处理将 FlushMode 设置为 MANUAL,以确保不会刷新对托管持久实体的任何正在进行的更改,同时以事务方式读取新对象。
为了完整起见,我的 spring-web-flow 配置:
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:webflow="http://www.springframework.org/schema/webflow-config"
xmlns="http://www.springframework.org/schema/beans"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/webflow-config
http://www.springframework.org/schema/webflow-config/spring-webflow-config.xsd">
<!-- Flow executor, repsonsible for creating and executing flows -->
<webflow:flow-executor id="flowExecutor" flow-registry="flowRegistry">
<webflow:flow-execution-listeners>
<webflow:listener ref="jpaFlowExecutionListener"/>
</webflow:flow-execution-listeners>
</webflow:flow-executor>
<!-- Flow registry, responsible for loading all flows so executor can execute them -->
<webflow:flow-registry id="flowRegistry" base-path="/WEB-INF/webflow/flows" flow-builder-services="flowBuilderServices">
<webflow:flow-location-pattern value="/**/*-flow.xml"/>
</webflow:flow-registry>
<!-- Flow builder services -->
<webflow:flow-builder-services id="flowBuilderServices" view-factory-creator="mvcViewFactoryCreator"/>
<!-- MvcViewFactoryCreator -->
<bean id="mvcViewFactoryCreator" class="org.springframework.webflow.mvc.builder.MvcViewFactoryCreator">
<property name="viewResolvers">
<list>
<ref bean="viewResolver"/>
</list>
</property>
</bean>
<!-- Flow handler adapter, responsible for answering request for a flow -->
<bean class="org.springframework.webflow.mvc.servlet.FlowHandlerAdapter">
<property name="flowExecutor" ref="flowExecutor"/>
</bean>
<!-- Flow handler mapping, lets Spring MVCs DispatcherServlet know to send flow request to SWF -->
<bean class="org.springframework.webflow.mvc.servlet.FlowHandlerMapping">
<property name="flowRegistry" ref="flowRegistry"/>
<property name="order" value="0"/>
<property name="interceptors">
<list>
<ref bean="localeChangeInterceptor" />
</list>
</property>
</bean>
</beans>
我的流量有<persistence-context />
定义在顶部。
我有以下最终状态(重新启动流程),即使我调用它并且 URL 参数更改为e2s1
,活动连接数不重置:
<end-state id="restart" commit="true" view="redirect:/main"/>