Tomcat连接池:几种不释放连接的方法

2024-01-11

我正在使用 tomcat 连接池。但我遵循例外org.apache.tomcat.dbcp.dbcp.SQLNestedException: Cannot get a connection, pool error Timeout waiting for idle object

因此,我在 context.xml 中添加了以下几行来查找泄漏:removeAbandoned="true" logAbandoned="true" removeAbandonedTimeout="3"

然后我开始出现以下异常org.apache.tomcat.dbcp.dbcp.AbandonedTrace$AbandonedObjectException: DBCP object created 2015-01-17 22:12:18 by the following code was never closed:所以我找到了导致此泄漏的两种罪魁祸首方法。这两种方法具有获取连接的共同方式,即调用 unwrap 来访问驱动程序特定的连接。

try (Connection conn = DataSourceConnectionPool.getConnection().unwrap(OracleConnection.class);
        OracleCallableStatement cstmt = (OracleCallableStatement) conn.prepareCall(MIGRATE_ACCOUNT)) {
        ...
        ....
)

需要注意的重要一点是,我使用的是 JDK7 中的 try 块,即自动资源管理,所以我不需要 finally 块。连接关闭由 JDK 自动处理。但为什么这个未包装的连接没有关闭。当我尝试执行以下操作时:

try (Connection poolConn = DataSourceConnectionPool.getConnection();
    Connection conn = poolConn.unwrap(OracleConnection.class);

我正进入(状态java.sql.SQLException: Already closed.那么这种联系有多紧密。我是否必须在不使用 try 块的情况下手动执行此操作?尝试块句柄不应该能够处理这个问题吗?


这是连接池的错误使用。你永远不应该打电话close()在未包装的连接上。

使用池化连接的正常流程是

  1. Get the Connection,池获取物理连接并将其包装在自己的包装器中返回
  2. 您使用Connection
  3. 你打电话close() on the Connection。这实际上并不close任何东西,池的包装器都会拦截close()调用并简单地将(仍然活动的)连接返回到池中。

这是有效的,因为池有一个包装类,例如PoolableConnection that implements Connection. PoolableConnection委托底层连接来执行实际工作,但它实现了(除其他外)close()不同。这会破坏当前的PoolableConnection包装器并返回底层Connection到连接池。例如。

这样,您的程序逻辑就可以从DataSource, 使用Connection进而close(),就像正常的、非池化的一样,Connection.

正是这种透明度使得连接池如此易于使用。

现在,当你打电话时unwrap, the PooledConnection让你能够接触到它的内部的、真实的、Connection代表。

What you要做的就是打电话close() 关于代表!

这有两个效果:

  1. 它不调用close() on PooledConnection,所以Connection不会返回到池中。
  2. 它从池下面关闭底层连接。这应该不是问题,因为池会自行处理断开的连接。

所以你需要非常小心。Always call close() on the Connection您已从池中取出,请将其放回池中。Never call close()在底层连接上。

所以你的代码应该是:

try (final Connection poolConn = DataSourceConnectionPool.getConnection()) {
    final Connection conn = poolConn.unwrap(OracleConnection.class);
    //do stuff with conn
    //do not close conn!!
}
//poolConn is returned to the pool
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Tomcat连接池:几种不释放连接的方法 的相关文章

随机推荐