DBCP返回已关闭的连接

我们看到来自org.apache.commons.dbcp.BasicDataSource的数据库连接因套接字写入错误而死的情况:

 com.microsoft.sqlserver.jdbc.SQLServerException: Connection reset by peer: socket write error 

当然,所有后续写入连接的尝试都会失败:

 com.microsoft.sqlserver.jdbc.SQLServerException: The connection is closed. 

更新代码以捕获此类exception并在发生新连接时请求它,它再次失败。 我是否正确怀疑调用DataSource#getConnection()实际上每次调用时都没有提供新连接? 是不是只是重用现有的连接,这是关闭的?

如果我是正确的,什么是扔掉旧连接并请求新连接的正确方法?

编辑:这是我想知道的更简洁的版本:

 Connection c1, c2; c1 = DatabaseManager.getConnection(); // c1.close() not called c2 = DatabaseManager.getConnection(); 

“c1 == c2”是真实的陈述吗? 或者分配了两个连接? 如果是后者,那么像这样的代码表示“连接池泄漏”:

 Connection c1; c1 = DatabaseManager.getConnection(); // c1.close() not called c1 = DatabaseManager.getConnection(); 

汇总连接已由DB关闭。 这可能意味着两件事:

  1. 连接池将连接打开的时间过长。
  2. DB在很短的时间后关闭连接。

理论上,增加/减少任何一方的超时以对齐它应该可以解决问题。

在DBCP上,最好的办法是在返回之前通过testOnBorrow=truevalidationQuery设置validation连接,例如SELECT 1 。 您可以在Tomcat JDBC数据源文档中找到配置选项。


根据您的更新进行更新:

这是我想知道的更简洁的版本:

 Connection c1, c2; c1 = DatabaseManager.getConnection(); // c1.close() not called c2 = DatabaseManager.getConnection(); 

“c1 == c2”是真实的陈述吗? 或者分配了两个连接?

这是两个截然不同的联系。 只有当你调用c1.close()c2才有可能返回相同的连接。

如果是后者,那么像这样的代码表示“连接池泄漏”:

 Connection c1; c1 = DatabaseManager.getConnection(); // c1.close() not called c1 = DatabaseManager.getConnection(); 

是的,肯定会泄漏第一个连接,因为它从未被返回到池中。 您应该始终try-finally块中以try-finally短的范围关闭所有数据库资源。 然而,有点像样的连接池可以配置以获得废弃的连接,但这绝对不能用作“解决方法”。

我也面临同样的问题。 然后我意识到我正在进行多个异步ajax调用,导致问题。

我序列化了调用并解决了问题。