2015-10-15 34 views
1

我正在使用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次,但该作品一个小的测试方法精细。

+1

您的crp0配置在哪里? –

+0

我以编程的方式对其进行配置,我将在短时间内对其进行编辑 – svarog

+1

以及@Steve Waldman的回答,他指向一个已被绞死的线程,所以您是否使用不同的线程来打开连接并使用连接 ?如果你在一个线程中使用连接,这个线程不是上下文感知的(意味着tomcat不知道它的存在),当另一个线程要求连接池时,tomcat积极地中断第一个线程来传递连接第二个线程 – AntJavaDev

回答

2

c3p0-0.9.1.2非常非常古老;请考虑升级到当前量产版本0.9.5.1。

问题既清楚又不那么清楚。清晰的部分是,正在等待获取Connections的客户端线程上正在调用interrupt()。不太清楚的部分是谁在做这件事,为什么。

一个猜测是Tomcat本身正在这样做,因为客户端线程挂起时间过长。如果线程挂在getConnection(),这可能是由于连接泄漏和池耗尽。我们在上面看到您如何获得Connections。你是否保持警惕,确保它们在最后的块中可靠地被编辑?

您可能会尝试的一件事是设置一个checkoutTimeout,例如,

cpds.setCheckoutTimeout(5000); // 5 secs 

这实际上不会解决问题,如果连接检出正在挂起。但不是由神秘的中断引发的问题,你会看到c3p0 TimeoutExceptions。尽管如此,这将验证问题在结帐时很长时间,这很可能是由于连接泄漏(缺少对close()的调用)或简单地从您的负载的maxPoolSize值太低而引起的连接池耗尽。

如果似乎存在连接泄漏,请参阅unreturnedConnectionTimeoutdebugUnreturnedConnectionStackTraces以获取帮助追踪。另请参阅"Configuring to Debug and Workaround Broken Client Applications"

+0

我注意到了旧版本并升级了。问题依然存在。接受你的建议,我已经设置了setCheckoutTimeout(500)并得到:java.sql.SQLException:客户端尝试检出连接超时。 异常。池很快耗尽,我猜想可能是问题所在。 – svarog

+0

(我会尝试5000而不是500毫秒,通常连接应该在500毫秒内检出,但如果池暂时耗尽,因为它需要扩展或因为其他客户端正在使用连接但很快会返回它们,可能你可能会偶尔看到那种延迟,我怀疑它不会有太大的区别,但你仍然会看到超时。) –

+0

('unreturnedConnectionTimeout'和'debugUnreturnedConnectionStackTraces'对于查找非常有用连接泄漏。) –