DBCP返回已关闭的连接

时间:2011-09-08 15:34:33

标签: java jdbc apache-commons-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.

更新代码以捕获此类异常并在发生新连接时请求它,它再次失败。我是否正确怀疑调用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();

2 个答案:

答案 0 :(得分:10)

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

  1. 连接池保持连接打开时间过长。
  2. DB在很短的时间后关闭连接。
  3. 理论上,增加/减少任何一方的超时以对齐它应该可以解决问题。

    在DBCP上,您最好的选择是在通过testOnBorrow=truevalidationQuery设置返回之前验证连接,例如: 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调用,导致问题。

我序列化了这些电话并解决了这个问题。