在使用C3P0时,如何最好地关闭连接并避免非活动会话?

Chi*_*lax 4 database spring jpa connection-pooling c3p0

我正在使用c3p0进行连接池.我使用的ComboPooledDataSource配置如下.

@Bean
public DataSource dataSource() {

    ComboPooledDataSource dataSource = new ComboPooledDataSource();
    dataSource.setUser("user");
    dataSource.setDriverClass("oracle.jdbc.OracleDriver");
    dataSource.setJdbcUrl("test");
    dataSource.setPassword("test");
    dataSource.setMinPoolSize("10");
    dataSource.setMaxPoolSize("20");
    dataSource.setMaxStatements("100");
    return dataSource;
}
Run Code Online (Sandbox Code Playgroud)

我正面临着一些问题.我收到警告说这可能会泄漏连接.还有以下错误,不时

因为所有连接都在用完.

java.sql.SQLException: Io exception: Got minus one from a read call
    at oracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.java:112)
    at oracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.java:146)
    at oracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.java:255)
    at oracle.jdbc.driver.T4CConnection.logon(T4CConnection.java:387)
    at oracle.jdbc.driver.PhysicalConnection.<init>(PhysicalConnection.java:439)
    at oracle.jdbc.driver.T4CConnection.<init>(T4CConnection.java:165)
    at oracle.jdbc.driver.T4CDriverExtension.getConnection(T4CDriverExtension.java:35)
    at oracle.jdbc.driver.OracleDriver.connect(OracleDriver.java:801)
    at com.mchange.v2.c3p0.DriverManagerDataSource.getConnection(DriverManagerDataSource.java:135)
    at com.mchange.v2.c3p0.WrapperConnectionPoolDataSource.getPooledConnection

(WrapperConnectionPoolDataSource.java:182)
    at com.mchange.v2.c3p0.WrapperConnectionPoolDataSource.getPooledConnection

(WrapperConnectionPoolDataSource.java:171)
    at com.mchange.v2.c3p0.impl.C3P0PooledConnectionPool$1PooledConnectionResourcePoolManager.acquireResource

(C3P0PooledConnectionPool.java:137)
    at com.mchange.v2.resourcepool.BasicResourcePool.doAcquire(BasicResourcePool.java:1014)
    at com.mchange.v2.resourcepool.BasicResourcePool.access$800(BasicResourcePool.java:32)
    at com.mchange.v2.resourcepool.BasicResourcePool$AcquireTask.run(BasicResourcePool.java:1810)
    at com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread.run(ThreadPoolAsynchronousRunner.java:547)
Run Code Online (Sandbox Code Playgroud)

从DB stat,可以看到近290个非活动连接.我在两台服务器上部署了大约8个应用程序,

连接到同一个DB.

我的疑问是

  1. 如何确保连接已关闭且没有这些非活动连接?
  2. 配置空闲时间和超时是否可以解决此问题?
  3. 如果服务器关闭/ tomcat关闭会发生什么,连接是否会保持打开状态?
  4. 连接主要在启动期间用于加载缓存,那么之后是否有一种不使用这些连接的方法?
  5. 我应该如何处理现有的非活动连接?

Ste*_*man 8

  • 给定maxPoolSize20个和8个部署,您应该最多可以看到180个连接,如果应用程序已经看到流量已经消退,则可能处于非活动状态.您没有配置任何内容来鼓励快速缩减池 - 设置maxIdleTime和/或maxIdleTimeExcessConnections和/或maxConnectionAge.
  • 您应该告诉Spring如何关闭您定义的DataSource.在您的方法上使用@Bean(destroyMethodName="close")而不是@Bean单独使用dataSource().
  • 您尚未配置任何类型的连接测试,因此即使损坏的连接可能仍保留在池中.请参阅连接测试的简单建议.
  • 如果问题是连接泄漏,客户端最终将无限期挂起,因为池将不在Connections中检出,但已经到达maxPoolSize,因此无法从DBMS获取更多内容.你是否看到客户这样挂?
  • 在Java7之后,避免连接泄漏的方法是始终通过try-with-resources从DataSource获取Connections .也就是说,用...

    try ( Connection conn = myDataSource.getConnection() ) {
      ...
    }
    
    Run Code Online (Sandbox Code Playgroud)

    而不是仅仅调用getConnection()可能抛出异常或try块的方法.如果您使用的是旧版本的Java,则需要使用健壮的资源清理惯用法,即在try块中获取Connection 并确保conn.close()finally块中始终关闭,而不管finally块中的任何其他失败.如果您不DataSource直接使用,但让Spring实用程序使用它,希望这些实用程序正在做正确的事情.但是你应该发布你收到的任何警告警告你潜在的连接泄漏!

  • 如果您的应用程序在"预热"后很少使用Connections,并且您希望最小化资源占用,请设置minPoolSize为非常低的数字,并使用上述maxIdleTime和/或maxIdleTimeExcessConnections和/或maxConnectionAge来确保池当连接不再需要时,立即缩小规模.或者close(),当您完成其工作时,您可能是DataSource,但您可能将其留给Spring.