【发布时间】:2018-08-20 07:24:56
【问题描述】:
我有一个服务方法,它连接到 MySQL 并在 ResultSet 中获取数据,在 finally 中关闭它是 PreparedStatement,但 STS 在返回语句中显示警告为
潜在的资源泄漏:“resultSet”可能不会在此时关闭 位置
方法:
public boolean checkData() {
Connection dbConnection = null;
PreparedStatement preparedStatement = null;
ResultSet resultSet = null;
boolean status = false;
try {
dbConnection = icrud.getConnection();
preparedStatement = dbConnection.prepareStatement("query on table");
resultSet = preparedStatement.executeQuery();
if (resultSet.next()) {
status = resultSet.getBoolean("STATUS");
}
return status; //Potential resource leak warning shows here.
} catch (Exception e) {
LOGGER.error("Exception Occurred:: " , e);
} finally {
try {
if (preparedStatement != null) {
preparedStatement.close();
preparedStatement = null;
}
} catch (SQLException e) {
LOGGER.error("Exception Occured while Closing statement" , e);
}
try {
if (dbConnection != null) {
dbConnection.close();
dbConnection = null;
}
} catch (SQLException e) {
LOGGER.error("Exception Occured while closing connection" , e);
}
}
return status;
}
根据文档,
当一个 Statement 对象关闭时,它当前的 ResultSet 对象,如果 一个存在,也是封闭的。
所以我终于关闭了Statement,尽管它显示了警告。我已经通过关闭结果集进行了检查,最后仍然没有发出警告。
是误报吗?还是我做错了什么?
【问题讨论】:
-
因为 STS 不知道这个规则。它只是看到你创建了一个 Closeable,并没有明确地关闭它。所以这是一个潜在的资源泄漏。
-
@JBNizet 哦,所以这只是误报警告,可以安全忽略吗?我遵循的关闭数据库连接和资源的任何模式都是正确的?
-
这是不必要的复杂。 Java 从 Java 6 或 7 开始就有 try-with-resources。使用它。 docs.oracle.com/javase/tutorial/essential/exceptions/…
-
最重要的是,不要捕获异常,也不要忽略它。这个方法应该抛出一个 SQLException,而不是捕获它。或者如果发生 SQL 异常,至少抛出另一个异常。
-
@JBNizet 此外,鉴于连接池和语句池,关闭语句可能并不总是真正关闭结果集(通常在有问题的池实现或为“性能”采取捷径的池中)。