Tomcat8 + c3p0,连接中断并自动关闭
Tomcat8 + c3p0, connections are being interruped and auto closed
我正在 Tomcat 8 上使用 Maven 开发 Web 应用程序,我使用 c3p0 处理主线程和其他 2 个并发线程上的连接,我的连接管理器 class 是询问 DataSource 单例 class 我已经实现了同步连接,就像这样
public synchronized Connection getConnection() {
try {
return cpds.getConnection();
} catch (SQLException ex) {
logger.error("Error while issuing a pooled connection", ex);
}
return null;
}
,但是当我尝试使用这些连接时,它们开始中断
09:47:17.164 [QuartzScheduler_Worker-4] ERROR com.myapp.providers.DataSource - Error while issuing a pooled connection
java.sql.SQLException: An SQLException was provoked by the following failure: java.lang.InterruptedException
at com.mchange.v2.sql.SqlUtils.toSQLException(SqlUtils.java:106) ~[c3p0-0.9.1.2.jar:0.9.1.2]
at com.mchange.v2.sql.SqlUtils.toSQLException(SqlUtils.java:65) ~[c3p0-0.9.1.2.jar:0.9.1.2]
at com.mchange.v2.sql.SqlUtils.toSQLException(SqlUtils.java:62) ~[c3p0-0.9.1.2.jar:0.9.1.2]
at com.mchange.v2.c3p0.impl.C3P0PooledConnectionPool.checkoutPooledConnection(C3P0PooledConnectionPool.java:531) ~[c3p0-0.9.1.2.jar:0.9.1.2]
at com.mchange.v2.c3p0.impl.AbstractPoolBackedDataSource.getConnection(AbstractPoolBackedDataSource.java:128) ~[c3p0-0.9.1.2.jar:0.9.1.2]
或在交易中途关闭并破坏当时正在使用的任何语句和结果集
我正在像这样配置 DataSource 对象
cpds = new ComboPooledDataSource();
cpds.setDriverClass(oracle.jdbc.driver.OracleDriver);
cpds.setJdbcUrl(jdbc:oracle:thin:@xx.xxx.xxx.xxx:1521:XE);
cpds.setUser("username");
cpds.setPassword("password");
// database connection properties
cpds.setInitialPoolSize(10);
cpds.setAcquireIncrement(3);
cpds.setMaxPoolSize(100);
cpds.setMinPoolSize(15);
cpds.setMaxStatements(75);
// connection pool preferences
cpds.setIdleConnectionTestPeriod(60);
cpds.setMaxIdleTime(30000);
cpds.setAutoCommitOnClose(false);
cpds.setPreferredTestQuery("SELECT 1 FROM DUAL");
cpds.setTestConnectionOnCheckin(false);
cpds.setTestConnectionOnCheckout(false);
cpds.setAcquireRetryAttempts(30);
cpds.setAcquireRetryDelay(1000);
cpds.setBreakAfterAcquireFailure(false);
我也写了一个循环运行并查询数据库 n 次的小测试方法,但是工作正常。
c3p0-0.9.1.2 非常非常旧;请考虑升级到当前生产版本 0.9.5.1。
问题既清楚又不太清楚。清楚的部分是某些东西正在等待获取连接的客户端线程上调用 interrupt()
。不太清楚的部分是谁在做什么以及为什么。
猜测是 Tomcat 本身正在这样做,因为客户端线程挂起时间过长。如果线程在 getConnection()
挂起,那可能是由于连接泄漏和池耗尽。我们在上面看到了您如何获取连接。您是否警惕确保它们可靠地 close()
ed in finally 块?
您可以尝试设置 checkoutTimeout,例如
cpds.setCheckoutTimeout( 5000 ); // 5 secs
如果连接签出挂起,这实际上并不能解决问题。但是,您会看到 c3p0 TimeoutExceptions,而不是神秘中断引发的问题。这将验证问题是否在结帐时长时间挂起,这很可能是由于连接泄漏(缺少对 close()
的调用)或 maxPoolSize
值造成的池耗尽对你的负载来说太低了。
如果确实存在连接泄漏,请参阅 unreturnedConnectionTimeout and debugUnreturnedConnectionStackTraces for help tracking it down. See also "Configuring to Debug and Workaround Broken Client Applications"
我正在 Tomcat 8 上使用 Maven 开发 Web 应用程序,我使用 c3p0 处理主线程和其他 2 个并发线程上的连接,我的连接管理器 class 是询问 DataSource 单例 class 我已经实现了同步连接,就像这样
public synchronized Connection getConnection() {
try {
return cpds.getConnection();
} catch (SQLException ex) {
logger.error("Error while issuing a pooled connection", ex);
}
return null;
}
,但是当我尝试使用这些连接时,它们开始中断
09:47:17.164 [QuartzScheduler_Worker-4] ERROR com.myapp.providers.DataSource - Error while issuing a pooled connection
java.sql.SQLException: An SQLException was provoked by the following failure: java.lang.InterruptedException
at com.mchange.v2.sql.SqlUtils.toSQLException(SqlUtils.java:106) ~[c3p0-0.9.1.2.jar:0.9.1.2]
at com.mchange.v2.sql.SqlUtils.toSQLException(SqlUtils.java:65) ~[c3p0-0.9.1.2.jar:0.9.1.2]
at com.mchange.v2.sql.SqlUtils.toSQLException(SqlUtils.java:62) ~[c3p0-0.9.1.2.jar:0.9.1.2]
at com.mchange.v2.c3p0.impl.C3P0PooledConnectionPool.checkoutPooledConnection(C3P0PooledConnectionPool.java:531) ~[c3p0-0.9.1.2.jar:0.9.1.2]
at com.mchange.v2.c3p0.impl.AbstractPoolBackedDataSource.getConnection(AbstractPoolBackedDataSource.java:128) ~[c3p0-0.9.1.2.jar:0.9.1.2]
或在交易中途关闭并破坏当时正在使用的任何语句和结果集
我正在像这样配置 DataSource 对象
cpds = new ComboPooledDataSource();
cpds.setDriverClass(oracle.jdbc.driver.OracleDriver);
cpds.setJdbcUrl(jdbc:oracle:thin:@xx.xxx.xxx.xxx:1521:XE);
cpds.setUser("username");
cpds.setPassword("password");
// database connection properties
cpds.setInitialPoolSize(10);
cpds.setAcquireIncrement(3);
cpds.setMaxPoolSize(100);
cpds.setMinPoolSize(15);
cpds.setMaxStatements(75);
// connection pool preferences
cpds.setIdleConnectionTestPeriod(60);
cpds.setMaxIdleTime(30000);
cpds.setAutoCommitOnClose(false);
cpds.setPreferredTestQuery("SELECT 1 FROM DUAL");
cpds.setTestConnectionOnCheckin(false);
cpds.setTestConnectionOnCheckout(false);
cpds.setAcquireRetryAttempts(30);
cpds.setAcquireRetryDelay(1000);
cpds.setBreakAfterAcquireFailure(false);
我也写了一个循环运行并查询数据库 n 次的小测试方法,但是工作正常。
c3p0-0.9.1.2 非常非常旧;请考虑升级到当前生产版本 0.9.5.1。
问题既清楚又不太清楚。清楚的部分是某些东西正在等待获取连接的客户端线程上调用 interrupt()
。不太清楚的部分是谁在做什么以及为什么。
猜测是 Tomcat 本身正在这样做,因为客户端线程挂起时间过长。如果线程在 getConnection()
挂起,那可能是由于连接泄漏和池耗尽。我们在上面看到了您如何获取连接。您是否警惕确保它们可靠地 close()
ed in finally 块?
您可以尝试设置 checkoutTimeout,例如
cpds.setCheckoutTimeout( 5000 ); // 5 secs
如果连接签出挂起,这实际上并不能解决问题。但是,您会看到 c3p0 TimeoutExceptions,而不是神秘中断引发的问题。这将验证问题是否在结帐时长时间挂起,这很可能是由于连接泄漏(缺少对 close()
的调用)或 maxPoolSize
值造成的池耗尽对你的负载来说太低了。
如果确实存在连接泄漏,请参阅 unreturnedConnectionTimeout and debugUnreturnedConnectionStackTraces for help tracking it down. See also "Configuring to Debug and Workaround Broken Client Applications"