如何在jdbc池中强制重用连接?
我有一个Runnable,它从连接池获取连接,如下所示,有60秒的时间对连接做一些事情:
private static ConnectionPoolDataSource cpds; // MysqlConnectionPoolDataSource public void run(){ while((System.currentTimeMillis()-created)<60000){ try(Connection conn = cpds.getPooledConnection().getConnection()){ //do something }catch(SQLException sqle){} } }
当线程在60s后死亡时,我假设连接被返回到池中,并且当创建新线程时,可以重新使用连接。 但是当我列出我的网络连接时,列表会随着创建更multithreading而不断增长。 如上所述创建的连接是否正确返回到池中,如果是这样,我如何强制重新使用连接?
您实际上并没有使用连接池。 ConnectionPoolDataSource
不能直接使用。 它旨在作为PooledConnection
对象的(特殊) DataSource
,然后通过提供连接池的(正常) DataSource
实现将其保存在连接池中。
普通开发人员不应直接使用ConnectionPoolDataSource
,它应与Application Server提供的连接池一起使用,或者包含在提供连接池的通用DataSource
。
当从连接池请求连接时,它将检出现有的PooledConnection
(或从其ConnectionPoolDataSource
请求新的PooledConnection
),检索Connection
并将其返回给用户。 当用户关闭Connection
, PooledConnection
将通知连接池它再次可用。
在这种情况下,您将创建一个PooledConnection
, PooledConnection
检索一个Connection
,然后丢弃PooledConnection
。 这意味着PooledConnection
被放弃了,它与数据库的物理连接无法重用,并且在最终被垃圾收集时将被关闭/丢弃(通常当连接池想要关闭物理连接时,它将调用close()
PooledConnection
)。
您需要使用Application Server提供的连接池,或使用DBCP,c3p0或BoneCP等通用连接池。
你没有说你正在使用什么连接池,所以答案是“也许”。
但是,大多数池都有一些方法可以检测废弃的连接。 例如, DBCP为您提供removeAbandoned
和removeAbandonedTimeout
配置参数。 这些不会立即返回到池的连接,所以你仍然可以看到连接数增加直到超时到期(希望,因为你处于紧密循环中,你已经设置了最大数量的连接打开连接)。