我们看到来自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.
更新代码以捕获此类异常并在发生新连接时请求它,它再次失败。我是否正确怀疑调用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();
答案 0 :(得分:10)
汇总连接已由DB关闭。这可能意味着两件事:
理论上,增加/减少任何一方的超时以对齐它应该可以解决问题。
在DBCP上,您最好的选择是在通过testOnBorrow=true
和validationQuery
设置返回之前验证连接,例如: SELECT 1
。您可以在Tomcat JDBC data sources documentation中找到配置选项。
更新:
这是我想知道的更为简洁的版本:
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
块中尽可能短的所有数据库资源。然而,有点像样的连接池可以配置以获得废弃的连接,但绝对不能用作“解决方法”。
答案 1 :(得分:1)
我也面临同样的问题。然后我意识到我正在进行多个异步ajax调用,导致问题。
我序列化了这些电话并解决了这个问题。