在JBoss 7中运行Java Web服务开发时,我遇到了在BBDD上管理池会话的奇怪错误。
我正在使用链接到Hibernate 4和Spring的Hikari组件来管理BBDD连接,完全在ORACLE中。
这是配置:
public DataSource dataSourceOracle() {
HikariConfig config = new HikariConfig();
config.setDataSourceClassName("oracle.jdbc.pool.OracleDataSource");
config.setMaximumPoolSize(20);
config.setMinimumIdle(5);
config.addDataSourceProperty("jdbc:oracle:thin:@XXXXXXX:1521:XXXXXXXXX");
config.addDataSourceProperty("XXXXXXXXXX");
config.addDataSourceProperty("XXXXXXXXXX");
config.addDataSourceProperty("user");
config.addDataSourceProperty("password");
return new HikariDataSource(config);
}
您可以检查I setup maximun pool size to 20 and minimun idle is 5。
因此,当WS运行并接收带有大量请求的负载测试时(我正在使用soapUI用于此目的),在BBDD上已经创建了20个非活动会话,但过了一段时间,这只会使用10个会话,因为你可以检查这个快照:
从不使用超过10个,尽管有10个非活动状态,但经常产生以下错误:
Could not open Hibernate Session for transaction; nested exception is org.hibernate.QueryTimeoutException: Could not open connection
at org.springframework.orm.hibernate4.HibernateTransactionManager.doBegin(HibernateTransactionManager.java:544) [spring-orm-4.1.7.RELEASE.jar:4.1.7.RELEASE]
at org.springframework.transaction.support.AbstractPlatformTransactionManager.getTransaction(AbstractPlatformTransactionManager.java:373) [spring-tx-4.1.7.RELEASE.jar:4.1.7.RELEASE]
at org.springframework.transaction.interceptor.TransactionAspectSupport.createTransactionIfNecessary(TransactionAspectSupport.java:463) [spring-tx-4.1.7.RELEASE.jar:4.1.7.RELEASE]
at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:276) [spring-tx-4.1.7.RELEASE.jar:4.1.7.RELEASE]
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:96) [spring-tx-4.1.7.RELEASE.jar:4.1.7.RELEASE]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) [spring-aop-4.0.9.RELEASE.jar:4.0.9.RELEASE]
at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:644) [spring-aop-4.0.9.RELEASE.jar:4.0.9.RELEASE]
这是RootConfig.java,包括所有配置:
package com.xxxx.mpo.ws.config;
import com.xxxx.mpo.data.amasis.ws.AmasisWebService;
import com.yyyy.zzzz.mpo.thirdparty.service.ws.intr.AenaService;
import com.yyyy.zzzz.mpo.thirdparty.service.ws.intr.KeopsService;
import com.yyyy.zzzz.mpo.thirdparty.service.ws.intr.SigmaService;
import com.zaxxer.hikari.HikariConfig;
import com.zaxxer.hikari.HikariDataSource;
import java.util.Properties;
import java.util.concurrent.TimeUnit;
import javax.persistence.EntityManagerFactory;
import javax.sql.DataSource;
import javax.xml.ws.Endpoint;
import org.apache.cxf.Bus;
import org.apache.cxf.jaxws22.EndpointImpl;
import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.config.PropertyPlaceholderConfigurer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.ImportResource;
import org.springframework.context.annotation.Primary;
import org.springframework.context.annotation.PropertySource;
import org.springframework.core.env.Environment;
import org.springframework.core.io.ClassPathResource;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.orm.hibernate4.HibernateTransactionManager;
import org.springframework.orm.hibernate4.LocalSessionFactoryBean;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter;
import org.springframework.transaction.annotation.EnableTransactionManagement;
/**
* Clase de configuración de los servicios web que se despliegan en este war
*
* @author
*/
@Configuration
@PropertySource(value = "config.properties")
@ComponentScan(basePackages = {
"com.xxxx.mpo.data.amasis",
"com.xxxx.mpo.ws.config",
"com.yyyy.zzzz.mpo.thirdparty"
})
@EnableJpaRepositories("com.xxxx.mpo.data.amasis.repository")
@EnableTransactionManagement
@ImportResource({
"classpath:META-INF/cxf/cxf.xml",
"classpath:META-INF/cxf/cxf-servlet.xml"
})
public class RootConfig {
// Inyectar el entorno de Spring para poder leer las propiedades
@Autowired
private Environment env;
// Inyectar bus usado para desplegar los servicios web
@Autowired
private Bus cxfBus;
/**
* Configurar el endpoint del WS para acceder a Amasis
* @param amasisWebService Implementación del WS de Amasis
* @return
*/
@Bean(name = "amasisWebServiceEndpoint")
@Autowired
public Endpoint amasisWebServiceEndpoint(AmasisWebService amasisWebService) {
EndpointImpl endpoint = new EndpointImpl(cxfBus, amasisWebService);
endpoint.publish(env.getProperty("ws.amasis.publishUrl"));
return endpoint;
}
/**
* Configurar el endpoint del WS para acceder a Keops
* @param keopsService Implementación del WS de Keops
* @return
*/
@Bean(name = "keopsWebServiceEndpoint")
@Autowired
public Endpoint keopsWebServiceEndpoint(KeopsService keopsService) {
EndpointImpl endpoint = new EndpointImpl(cxfBus, keopsService);
endpoint.publish(env.getProperty("ws.keops.publishUrl"));
return endpoint;
}
/**
* Configurar el endpoint del WS para acceder al FTP de Aena
* @param aenaService Implementación del WS de Aena
* @return
*/
@Bean(name = "aenaWebServiceEndpoint")
@Autowired
public Endpoint aenaWebServiceEndpoint(AenaService aenaService) {
EndpointImpl endpoint = new EndpointImpl(cxfBus, aenaService);
endpoint.publish(env.getProperty("ws.aena.publishUrl"));
return endpoint;
}
/**
* Configurar el endpoint del WS para acceder a Sigma
* @param sigmaService Implementacion del WS de Sigma
* @return
*/
@Bean(name = "sigmaWebServiceEndpoint")
@Autowired
public Endpoint sigmaWebServiceEndpoint(SigmaService sigmaService) {
EndpointImpl endpoint = new EndpointImpl(cxfBus, sigmaService);
endpoint.publish(env.getProperty("ws.sigma.publishUrl"));
return endpoint;
}
/**
* Configuración del DataSource para conectarse a Amasis
*
* @return DataSource
*/
@Bean
@Primary
public DataSource dataSource() {
HikariConfig config = new HikariConfig();
config.setDataSourceClassName(env.getProperty("datasource.amasis.driver"));
//config.addDataSourceProperty("url", env.getProperty("datasource.amasis.url"));
config.addDataSourceProperty("serverName", env.getProperty("datasource.amasis.host"));
//config.addDataSourceProperty("portNumber ", env.getProperty("datasource.amasis.port"));
config.addDataSourceProperty("databaseName", env.getProperty("datasource.amasis.database"));
config.addDataSourceProperty("user", env.getProperty("datasource.amasis.user"));
config.addDataSourceProperty("password", env.getProperty("datasource.amasis.password"));
config.setConnectionTestQuery("SELECT current date FROM sysibm.sysdummy1");
return new HikariDataSource(config);
}
/**
* Configuración del DataSource para conectarse a la DB de Aims(oracle)
* @return DataSourceOracle
*/
@Bean(name = "dataSourceOracle")
public DataSource dataSourceOracle() {
HikariConfig config = new HikariConfig();
config.setDataSourceClassName(env.getProperty("datasource.oracle.driver"));
config.setMaximumPoolSize(Integer.parseInt(env.getProperty("datasource.oracle.maximumPoolSize")));
config.setMaxLifetime(Integer.parseInt(env.getProperty("datasource.oracle.maxLifetime")));
config.setIdleTimeout(Integer.parseInt(env.getProperty("datasource.oracle.idleTimeout")));
config.setMinimumIdle(Integer.parseInt(env.getProperty("datasource.oracle.minimumIdle")));
config.addDataSourceProperty("url", env.getProperty("datasource.oracle.url"));
config.addDataSourceProperty("serverName", env.getProperty("datasource.oracle.host"));
config.addDataSourceProperty("databaseName", env.getProperty("datasource.oracle.database"));
config.addDataSourceProperty("user", env.getProperty("datasource.oracle.user"));
config.addDataSourceProperty("password", env.getProperty("datasource.oracle.password"));
//config.addDataSourceProperty("cachePrepStmts", env.getProperty("datasource.oracle.cachePrepStmts"));
//config.addDataSourceProperty("prepStmtCacheSize", env.getProperty("datasource.oracle.prepStmtCacheSize"));
//config.addDataSourceProperty("prepStmtCacheSqlLimit", env.getProperty("datasource.oracle.prepStmtCacheSqlLimit"));
return new HikariDataSource(config);
}
/**
* Configuración del DataSource para conectarse a la DB de MPO
* @return DataSource
*/
@Bean(name = "dataSourceMPO")
public DataSource dataSourceMPO() {
HikariConfig config = new HikariConfig();
config.setDataSourceClassName(env.getProperty("datasource.mpo.driver"));
config.addDataSourceProperty("url", env.getProperty("datasource.mpo.url"));
config.addDataSourceProperty("user", env.getProperty("datasource.mpo.user"));
config.addDataSourceProperty("password", env.getProperty("datasource.mpo.password"));
config.addDataSourceProperty("cachePrepStmts", env.getProperty("datasource.mpo.cachePrepStmts"));
config.addDataSourceProperty("prepStmtCacheSize", env.getProperty("datasource.mpo.prepStmtCacheSize"));
config.addDataSourceProperty("prepStmtCacheSqlLimit", env.getProperty("datasource.mpo.prepStmtCacheSqlLimit"));
return new HikariDataSource(config);
}
/**
* Crear propiedades de hibernate leyendo de las propiedades para un
* datasource específico
*
* @param dataSource Nombre del datasource
* @return Propiedades de hibernate
*/
private Properties sessionFactoryProperties(String dataSource) {
Properties properties = new Properties();
properties.put("hibernate.dialect", env.getProperty("datasource." + dataSource + ".hibernate.dialect"));
properties.put("hibernate.show_sql", env.getProperty("datasource." + dataSource + ".hibernate.showSql"));
properties.put("hibernate.hbm2ddl.auto", env.getProperty("datasource." + dataSource + ".hibernate.hbm2ddl"));
/*properties.put("hibernate.connection.autocommit", env.getProperty("datasource." + dataSource + ".hibernate.autocommit"));
properties.put("hibernate.transaction.factory_class", env.getProperty("datasource." + dataSource + ".hibernate.factoryClass"));*/
return properties;
}
/**
* Configuración del Session factory utilizado para conectarse a Amasis
*
* @return
*/
@Bean
@Primary
public LocalSessionFactoryBean sessionFactory() {
LocalSessionFactoryBean sessionFactoryBean = new LocalSessionFactoryBean();
sessionFactoryBean.setDataSource(dataSource());
sessionFactoryBean.setPackagesToScan(env.getRequiredProperty("datasource.amasis.packagesToScan"));
sessionFactoryBean.setHibernateProperties(sessionFactoryProperties("amasis"));
return sessionFactoryBean;
}
/**
* Configuración del Session factory utilizado para conectarse a Aims
*
* @return
*/
@Bean
public LocalSessionFactoryBean sessionFactoryAims() {
LocalSessionFactoryBean sessionFactoryBean = new LocalSessionFactoryBean();
sessionFactoryBean.setDataSource(dataSourceOracle());
//sessionFactoryBean.setPackagesToScan(env.getRequiredProperty("datasource.amasis.packagesToScan"));
sessionFactoryBean.setHibernateProperties(sessionFactoryProperties("aims"));
return sessionFactoryBean;
}
/**
* Configuración del Session Factory utilizado para conectarse a MPO
* @return Instancia del Session Factory
*/
@Bean(name = "sessionFactoryMPO")
public LocalSessionFactoryBean sessionFactoryMPO() {
LocalSessionFactoryBean sessionFactoryBean = new LocalSessionFactoryBean();
sessionFactoryBean.setDataSource(dataSourceMPO());
sessionFactoryBean.setPackagesToScan(env.getRequiredProperty("datasource.mpo.packagesToScan"));
sessionFactoryBean.setHibernateProperties(sessionFactoryProperties("mpo"));
return sessionFactoryBean;
}
/**
* Configuración del transaction manager
* @param sessionFactory Session factory
* @return Instancia del transaction manager
*/
@Bean(name = "transactionManager")
@Primary
@Autowired
public HibernateTransactionManager transactionManager(SessionFactory sessionFactory) {
HibernateTransactionManager transactionManager = new HibernateTransactionManager();
transactionManager.setSessionFactory(sessionFactory);
transactionManager.setDataSource(dataSource());
return transactionManager;
}
/**
* Configuración del transaction manager Aims (oracle)
* @param sessionFactory Session factory
* @return Instancia del transaction manager Aims
*/
@Bean(name = "transactionManagerOracle")
@Autowired
@Qualifier(value = "sessionFactoryAims")
public HibernateTransactionManager transactionManagerOracle(SessionFactory sessionFactory) {
HibernateTransactionManager transactionManager = new HibernateTransactionManager();
transactionManager.setSessionFactory(sessionFactory);
transactionManager.setDataSource(dataSourceOracle());
return transactionManager;
}
/**
* Configuración del transaction manager de MPO
* @param sessionFactory Session factory
* @return Instancia del transaction manager
*/
@Bean(name = "transactionManagerMPO")
@Autowired
@Qualifier(value = "sessionFactoryMPO")
public HibernateTransactionManager transactionManagerMPO(SessionFactory sessionFactory) {
HibernateTransactionManager transactionManager = new HibernateTransactionManager();
transactionManager.setSessionFactory(sessionFactory);
transactionManager.setDataSource(dataSourceMPO());
return transactionManager;
}
/**
* Configuración del jdbc template
*
* @return Instancia del jdbc template
*/
@Bean
public JdbcTemplate jdbcTemplate() {
JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource());
return jdbcTemplate;
}
/**
* Configurar EntityManagerFactory
* @return Instancia de EntityManagerFactory
*/
@Bean
@Primary
public EntityManagerFactory entityManagerFactory() {
HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
vendorAdapter.setGenerateDdl(true);
LocalContainerEntityManagerFactoryBean factory = new LocalContainerEntityManagerFactoryBean();
factory.setJpaVendorAdapter(vendorAdapter);
factory.setPackagesToScan(env.getRequiredProperty("datasource.amasis.packagesToScan"));
factory.setDataSource(dataSource());
factory.afterPropertiesSet();
return factory.getObject();
}
/**
* Configurar EntityManagerFactory de MPO
*
* @return Instancia de EntityManagerFactory
*/
@Bean(name = "entityManagerFactoryMPO")
public EntityManagerFactory entityManagerFactoryMPO() {
HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
vendorAdapter.setGenerateDdl(true);
LocalContainerEntityManagerFactoryBean factory = new LocalContainerEntityManagerFactoryBean();
factory.setJpaVendorAdapter(vendorAdapter);
factory.setPackagesToScan(env.getRequiredProperty("datasource.mpo.packagesToScan"));
factory.setDataSource(dataSourceMPO());
factory.afterPropertiesSet();
return factory.getObject();
}
/**
* Configurar origen de las propiedades
* @return Instancia de PropertyPlaceholderConfigurer
*/
@Bean
public static PropertyPlaceholderConfigurer propertyPlaceholderConfigurer() {
PropertyPlaceholderConfigurer propertyConfigurer = new PropertyPlaceholderConfigurer();
propertyConfigurer.setLocation(new ClassPathResource("com/yyyy/zzzz/mpo/ws/config.properties"));
return propertyConfigurer;
}
}
拜托,您能帮助我如何使用这10个以上的会话并避免这些错误吗?
亲切的问候,