Tomcat8 + c3p0,连接正在被中断并自动关闭
我正在使用Maven在Tomcat 8上开发一个Web应用程序,我正在使用c3p0来处理主线程和另外两个并发线程上的连接,我的连接管理器类在问一个DataSource单例类我为同步连接实现的,像这样Tomcat8 + c3p0,连接正在被中断并自动关闭
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]
或接近中等交易和打破任何陈述和结果集E是当时使用的
我配置像这样
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);
DataSource对象我也写的是在一个循环中运行,并查询数据库n次,但该作品一个小的测试方法精细。
c3p0-0.9.1.2非常非常古老;请考虑升级到当前量产版本0.9.5.1。
问题既清楚又不那么清楚。清晰的部分是,正在等待获取Connections的客户端线程上正在调用interrupt()
。不太清楚的部分是谁在做这件事,为什么。
一个猜测是Tomcat本身正在这样做,因为客户端线程挂起时间过长。如果线程挂在getConnection()
,这可能是由于连接泄漏和池耗尽。我们在上面看到您如何获得Connections。你是否保持警惕,确保它们在最后的块中可靠地被编辑?
您可能会尝试的一件事是设置一个checkoutTimeout,例如,
cpds.setCheckoutTimeout(5000); // 5 secs
这实际上不会解决问题,如果连接检出正在挂起。但不是由神秘的中断引发的问题,你会看到c3p0 TimeoutExceptions。尽管如此,这将验证问题在结帐时很长时间,这很可能是由于连接泄漏(缺少对close()
的调用)或简单地从您的负载的maxPoolSize
值太低而引起的连接池耗尽。
如果似乎存在连接泄漏,请参阅unreturnedConnectionTimeout和debugUnreturnedConnectionStackTraces以获取帮助追踪。另请参阅"Configuring to Debug and Workaround Broken Client Applications"
我注意到了旧版本并升级了。问题依然存在。接受你的建议,我已经设置了setCheckoutTimeout(500)并得到:java.sql.SQLException:客户端尝试检出连接超时。 异常。池很快耗尽,我猜想可能是问题所在。 – svarog
(我会尝试5000而不是500毫秒,通常连接应该在500毫秒内检出,但如果池暂时耗尽,因为它需要扩展或因为其他客户端正在使用连接但很快会返回它们,可能你可能会偶尔看到那种延迟,我怀疑它不会有太大的区别,但你仍然会看到超时。) –
('unreturnedConnectionTimeout'和'debugUnreturnedConnectionStackTraces'对于查找非常有用连接泄漏。) –
您的crp0配置在哪里? –
我以编程的方式对其进行配置,我将在短时间内对其进行编辑 – svarog
以及@Steve Waldman的回答,他指向一个已被绞死的线程,所以您是否使用不同的线程来打开连接并使用连接 ?如果你在一个线程中使用连接,这个线程不是上下文感知的(意味着tomcat不知道它的存在),当另一个线程要求连接池时,tomcat积极地中断第一个线程来传递连接第二个线程 – AntJavaDev