Tomcat8 + c3p0,连接被干扰并自动关闭

时间:2015-10-15 07:10:46

标签: java maven c3p0 tomcat8

我正在使用Maven在Tomcat 8上开发一个Web应用程序,我使用c3p0来处理主线程和另外两个并发线程上的连接,我的连接管理器类正在询问一个DataSource单例类I& #39;已实现同步连接,如此

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次,但工作正常。

1 个答案:

答案 0 :(得分:2)

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

问题既清楚又不那么清楚。明确的部分是某些东西在等待获取Connections的客户端线程上调用interrupt()。不太清楚的部分是谁在做这件事以及为什么。

猜测是Tomcat本身就是这样做的,因为客户端线程挂起的时间太长了。如果线程挂起getConnection(),则可能是由于连接泄漏和池耗尽造成的。我们在上面看到你如何获得Connections。你是否警惕确保它们在finally块中可靠close()

您可能尝试的是设置checkoutTimeout,例如

cpds.setCheckoutTimeout( 5000 ); // 5 secs

如果Connection checkout挂起,这实际上不会解决问题。但是,不是由神秘中断引发的问题,而是会看到c3p0 TimeoutExceptions。这将验证问题是否在结账时长时间挂起,这很可能是由于池泄漏,或者来自Connection泄漏(缺少对close()的调用),或者仅仅来自maxPoolSize值太低了你的负担。

如果确实存在连接泄漏,请参阅unreturnedConnectionTimeoutdebugUnreturnedConnectionStackTraces以获取有关跟踪的帮助。另请参阅"Configuring to Debug and Workaround Broken Client Applications"