java - 连接对象 close() 没有正确关闭连接

标签 java mysql jdbc connection driver

我正在使用以下代码片段连接数据库

private Connection getConnection(JspWriter out, String host, String dbname,
        String port, String user, String pwd) {
    try {
        if (host == null || dbname == null) {
            throw new IllegalArgumentException("Invalid host or dbname"); 
        }
        String url = "jdbc:mysql://" + host + ":" + port + "/" + dbname; 
        String clazz = "org.gjt.mm.mysql.Driver"; 
        Driver driver = (Driver) Class.forName(clazz).newInstance();
        DriverManager.registerDriver(driver);
        return DriverManager.getConnection(url, user, pwd);
    } catch (Exception e) {
       System.out.println("Exception occured while get connection :"+ e);
   }
    return null;
}

执行查询后,我将关闭连接对象

private JSONArray executeQuery(JspWriter out, Connection connection,String query, Object[] params) throws Exception {

PreparedStatement st = null;
ResultSet rs = null;
try {
    //connection = getConnection();
    st = connection.prepareStatement(query);
    int c = 1;
    for (Object param : params) {
        st.setObject(c++, param);
    }
    rs = st.executeQuery();
    if (rs == null) {
        return null;
    }
    ResultSetMetaData meta = rs.getMetaData();
    List<String> columns = getColumnNames(meta);
    JSONArray json = new JSONArray();
    while (rs.next()) {
        JSONObject obj = new JSONObject();
        for (String column : columns) {
            obj.put(column, rs.getObject(column));
        }
        json.put(obj);
    }
    return json;
} catch (Exception e) {
        System.out.println("Exception occurred while execute query" + e);
} finally {
    try {
        if (rs != null) {
            rs.close();
        } 
    } catch(Exception ex) {
            //Print exception
    }
    try {
        if (st != null) {
            st.close();
        }
    } catch(Exception ex) {
            //Print exception
    } 
    try {
        if(connection != null) {
                connection.close();
        }
        if(connection.isClosed()) {
            connection = null;
            }
        } catch(Exception ex) {
                //Print exception
        }
    }
    return null;
  }

虽然我已经用 .close() 方法关闭了连接。我确保连接已关闭 connection.closed() 并返回 true - 表示连接已成功关闭。

一旦连接限制达到最大值 - 我得到 DB Connection Exhausted 并且我的服务器无法建立进一步的连接。

有人可以帮我进一步调试吗。

最佳答案

不严格相关。使用 try-with-resources

开始使用 try-with-resources syntax ,这是在 Java 7 中引入的:

try (Connection connection = getConnection();
     PreparedStatement st = connection.prepareStatement(query)) {

    // ...
    try (ResultSet rs = st.executeQuery()) {

        // ...
    }
}

它更方便,更不容易出错。

关闭连接由谁负责?

关闭连接的责任始终是打开它的逻辑。如果您的方法未获取连接,则不应关闭连接。来电者应该(您尚未发布其逻辑)。理想情况下,无论如何您都会使用连接池,但这可能与本文无关。

一个例子:

// This logic opens the connection by calling getConnection()
// It must also close the connection again, e.g. with try-with-resources
try (Connection connection = getConnection()) {
  doSomething(connection);
}

...
// This logic didn't open a connection. It receives it from someone else
// It mustn't close the connection!
void doSomething(Connection connection) {

  // But if other resources are opened, then they must be closed here:
  try (Statement stmt = connection.createStatement()) {
    doSomething(stmt);
  }
}

..
// Again, this method didn't open the statement, it shouldn't close it
void doSomething(Statement statement) {
  ..
}

关于java - 连接对象 close() 没有正确关闭连接,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50327403/

相关文章:

java - 无法找到或加载主类 $JAVA_OPTS

java - 相同的 Java 源代码编译为二进制不同的类

mysql - 如何替换json数组的标签并在数组之前添加信息

mysql - 更改 phpmyadmin 中的默认字段

c# - 安全异常 ASP.NET/MySQL

mysql - 如何修复此 java mysql 异常 : Communications link failure?

java - 使用 Apache poi 在 excel 中查找特定列中的最后一行 no

java - 如何将永久 CLASSPATH 添加到 Mac OS El Capitan 上的终端?

java - jdbc 代码中的错误 -> com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException : You have an error in your SQL syntax

java - com.microsoft.sqlserver.jdbc.SQLServerException : The value is not set for the parameter number 1