Spring Web请求和Quartz触发的作业混合使用了这个池。运行大约5次后,池中没有可用的连接,initialsize=5,maxactive=10。增加maxActive没有什么作用,它只是在池空之前需要更长的时间和更多的石英运行。
2016-05-19 08:59:46,027 DEBUG org.springframework.scheduling.quartz.SchedulerFactoryBean#0_QuartzSchedulerThread QuartzSchedulerThread.run 276 : batch acquisition of 1 triggers
2016-05-19 09:00:00,001 DEBUG org.springframework.scheduling.quartz.SchedulerFactoryBean#0_QuartzSchedulerThread QuartzSchedulerThread.run 276 : batch acquisition of 0 triggers
2016-05-19 09:00:00,003 DEBUG org.springframework.scheduling.quartz.SchedulerFactoryBean#0_Worker-6 JobRunShell.run 201 : Calling execute on job DEFAULT.refMigrDetail
2016-05-19 09:00:00,003 DEBUG org.springframework.scheduling.quartz.SchedulerFactoryBean#0_Worker-6 DataSourceUtils.doGetConnection 110 : Fetching JDBC Connection from DataSource
2016-05-19 09:00:24,409 DEBUG org.springframework.scheduling.quartz.SchedulerFactoryBean#0_QuartzSchedulerThread QuartzSchedulerThread.run 276 : batch acquisition of 0 triggers
2016-05-19 09:00:30,004 ERROR org.springframework.scheduling.quartz.SchedulerFactoryBean#0_Worker-6 CMRoreReferenceMigrator.run 93 : org.springframework.jdbc.CannotGetJdbcConnectionException: Could not get JDBC Connection; nested exception is java.sql.SQLException: [org.springframework.scheduling.quartz.SchedulerFactoryBean#0_Worker-6] Timeout: Pool empty. Unable to fetch a connection in 30 seconds, none available[10 in use].
2016-05-19 09:00:49,378 DEBUG org.springframework.scheduling.quartz.SchedulerFactoryBean#0_QuartzSchedulerThread QuartzSchedulerThread.run 276 : batch acquisition of 0 triggers
我到目前为止所做的:
<bean id="rrfecfDataSource" class="org.apache.tomcat.jdbc.pool.DataSource" destroy-method="close">
<property name="driverClassName" value="${rrfecf.datasource.jdbcDriver}" />
<property name="url" value="${rrfecf.dataousrce.databaseUrl}" />
<property name="username" value="${rrfecf.datasource.username}" />
<property name="password" value="${password:rrfecf.datasource}" />
<property name="initialSize" value="5" />
<property name="maxActive" value="10" />
<property name="defaultAutoCommit" value="false" />
<property name="maxIdle" value="5" />
<property name="minIdle" value="0" />
<property name="testOnBorrow" value="true" />
<property name="testOnReturn" value="false" />
<property name="testWhileIdle" value="true" />
<property name="validationQuery" value="SELECT CURRENT_DATE FROM sysibm.sysdummy1" />
<property name="timeBetweenEvictionRunsMillis" value="600000" /> <!-- 10 minutes -->
<property name="minEvictableIdleTimeMillis" value="900000" /> <!-- 15 minutes -->
</bean>
<bean id="rrfecfSqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="configLocation" value="WEB-INF/sqlMapConfig.xml"/>
<property name="dataSource" ref="rrfecfDataSource" />
</bean>
这“似乎”起作用,不确定是否有更好的方法:
ApplicationContextAware类:
import org.apache.tomcat.jdbc.pool.DataSource;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
/**
* <p>
* The <code>BatchApplicationContextProvider</code> provides...
* </p>
*/
public class BatchApplicationContextProvider implements ApplicationContextAware {
public static final String ID = BatchApplicationContextProvider.class.getName ();
private String SHORT_NAME = "BatchApplicationContextProvider()";
@SuppressWarnings("unused")
private String SYSTEM_IDENTITY = String.valueOf ( System.identityHashCode ( this ) );
private ApplicationContext context;
/**
*
*/
public BatchApplicationContextProvider() {
// TODO Auto-generated constructor stub
}
/* (non-Javadoc)
* @see org.springframework.context.ApplicationContextAware#setApplicationContext(org.springframework.context.ApplicationContext)
*/
@Override
public void setApplicationContext(ApplicationContext arg0)
throws BeansException {
this.context = arg0;
}
public ApplicationContext getApplicationContext() {
return context;
}
public org.apache.tomcat.jdbc.pool.DataSource getConnectionPool () {
return ( DataSource ) this.context.getBean ( "rrfecfDataSource" );
}
}
public void dumpConnectionPool () {
org.apache.tomcat.jdbc.pool.DataSource lthePool = null;
ConnectionPool lbusyPool = null;
try {
lthePool = getBatchContext ().getConnectionPool ();
lbusyPool = lthePool.getPool ();
if ( lbusyPool != null ) {
if ( lbusyPool.getSize () > 0 ) {
getLog().info ( SHORT_NAME + ".run() - ConnectionPool - size....................[" + lbusyPool.getSize () + "] idle [" + lbusyPool.getIdle () + "] active [" + lbusyPool.getActive () + "]" );
//getLog().info ( SHORT_NAME + ".run() - ConnectionPool - idle....................[" + lbusyPool.getIdle () + "]" );
//getLog().info ( SHORT_NAME + ".run() - ConnectionPool - active..................[" + lbusyPool.getActive () + "]" );
//PoolConfiguration lpoolCfg = lbusyPool.getPoolProperties ();
}
}
lbusyPool = null;
lthePool = null;
}
catch ( Exception ltheXcp ) {
log.error ( ltheXcp );
}
finally {
}
}
EDIT:取出for循环...设置connection=null并没有将其释放回连接池。
成功:
dumpConnectionPool()虽然不漂亮,但它本身显示了问题清单:
2016-05-20 11:20:00,078 INFO org.springframework.scheduling.quartz.SchedulerFactoryBean#0_Worker-2 RunReferenceMigrator.run 138 : -----------------------------------------------------------------------------------------------------------------
2016-05-20 11:20:00,078 INFO org.springframework.scheduling.quartz.SchedulerFactoryBean#0_Worker-2 RunReferenceMigrator.dumpConnectionPool 257 : RunReferenceMigrator().run() - ConnectionPool - size....................[5] idle [5] active [0]
2016-05-20 11:20:00,078 INFO org.springframework.scheduling.quartz.SchedulerFactoryBean#0_Worker-2 RunReferenceMigrator.run 140 : -----------------------------------------------------------------------------------------------------------------
2016-05-20 11:24:45,063 INFO org.springframework.scheduling.quartz.SchedulerFactoryBean#0_Worker-2 RunReferenceMigrator.run 161 : -----------------------------------------------------------------------------------------------------------------
2016-05-20 11:24:45,063 INFO org.springframework.scheduling.quartz.SchedulerFactoryBean#0_Worker-2 RunReferenceMigrator.dumpConnectionPool 257 : RunReferenceMigrator().run() - ConnectionPool - size....................[5] idle [4] active [1]
2016-05-20 11:24:45,063 INFO org.springframework.scheduling.quartz.SchedulerFactoryBean#0_Worker-2 RunReferenceMigrator.run 163 : -----------------------------------------------------------------------------------------------------------------
null 如果我理解正确的话,我们应该在启动时有1个空闲连接,根据负载从0到3,对吗? 正在发生的情况是:启动时1个连接,如果负载较低,最多3个空闲连接,高负载后超过3个空闲连接。然后这些连接不会立即关闭,我们不知道它们何时/是否会关闭(有时它们中的一些会关闭)。 所以问题是:这种行为正常吗? DAO子类的使用示例:
我们有一个spring-boot应用程序,它使用嵌入式tomcat进行部署,并使用MySQL后端的默认tomcat-jdbc连接池,而没有为MySQL或tomcat端定制。 该应用程序有一些调度程序,它们主要在一天中的特定时间运行,即在昨天的最后一次cron运行和今天的第一次cron运行之间,有超过9个小时的间隙。然而,无论何时cron在早期运行,它都从未遇到过空闲连接问题。 现在我们看到一条错误
我们刚刚从dbcp迁移到tomcat jdbc连池。我们在加载中尝试了系统,收到了以下异常: 请注意: 不忙的连接在哪里?忙的数字在这之后一直在下降,但我们仍然没有得到任何连接。 有什么想法吗? 配置: env:ubuntu和tomcat 6. db-mysql
我在项目中使用ApacheTomcat JDBC连接池。我很困惑,因为在重负下,我一直看到以下错误: 我的期望是,使用池,新连接的请求将被保留在队列中,直到连接可用。相反,当池达到容量时,请求似乎会被拒绝。这种行为可以改变吗? 谢谢, 达尔 这是我的池配置:
这是我目前的配置 这是在全局上下文中,因此多个应用程序可以使用它。我对parameters.need一些细节有点困惑。我理解的是 池启动时创建的连接数。 一次最多可以激活50个连接。 10个连接在未使用连接时保持空闲,其他连接在 20个连接可以存储为空闲。 但当我启动tomcat服务器时,我可以看到30个空闲连接,这些连接将永远存在。为什么会这样?我错过什么了吗?根据我对连接池的理解,应该只创建1
Tomcat在使用后不释放连接的原因可能是什么? 这是我的配置