PreparedStatement 中的 Java 资源泄漏
Posted
技术标签:
【中文标题】PreparedStatement 中的 Java 资源泄漏【英文标题】:Java resource leak in PreparedStatement 【发布时间】:2014-10-17 08:22:45 【问题描述】:我正在用 Java 编写涉及数据库 (SQLite) 的代码,而且我是新手,所以我需要这方面的帮助。 我的代码如下所示:
Connection connection = null;
try
connection = SQLiteConnector.getConnection(database Name);
PreparedStatement prepStat = connection.prepareStatement("some SQL stuff");
ResultSet result= prepStat.executeQuery();
// Use of result
if (condition1)
prepStat = connection.prepareStatement("some SQL stuff");
result = prepStat.executeQuery();
// Another use of result
if (condition2)
prepStat = connection.prepareStatement("some SQL stuff");
else
prepStat = connection.prepareStatement("some SQL stuff");
result = prepStat.executeQuery();
// Use of result
result.close();
prepStat.close();
catch (Exception e)
// Exception management
finally
SQLiteConnector.closeConnection(connection);
我在 else 块中收到异常消息:“资源泄漏:'stat' 未在此位置关闭”。我应该如何重构它?
提前谢谢你
【问题讨论】:
发布堆栈跟踪并指向抛出它的行。还是编译时错误? 资源泄漏消息只是一个警告 - 如果您不解决该问题,您的代码仍将编译和运行。假设您的意思是prepStat
而不是stat
,警告是否显示在prepStat.close();
行或附近?另外,您使用的是哪个版本的 JDK?
你好像不是.close()
“第一”prepStat
,是吗?
看看这个***.com/questions/22096398/…,你必须关闭preparedStatement才能重用它。
另外,如果你使用 Java 7+,PreparedStatement
实现 AutoCloseable
所以你可能想要使用 try-with-resources 块
【参考方案1】:
PreparedStatements 应始终在 JDBC 中显式关闭。使用 PreparedStatement 的一般模式是:
创建语句。 设置参数并执行。 设置不同的参数并执行。 设置更多参数并执行。 关闭语句。从 Java 7 开始,确保始终正确执行此操作的最简单方法是在 try with resources 块中使用语句。
【讨论】:
【参考方案2】:使用单独的变量,绝对是 try-with-resources。
try (PreparedStatement prepStat =
connection.prepareStatement("some SQL stuff");
ResultSet result = prepStat.executeQuery())
...
try (PreparedStatement prepStat2 =
connection.prepareStatement(condition2 ? "some SQL stuff" : "some SQL stuff")
try (ResultSet result2 = prepStat.executeQuery();
// Use of result2
然后一切都很好地结束了,即使有异常或返回语句。
【讨论】:
【参考方案3】:您在重新使用之前没有关闭 prepStat。还要尝试关闭 finally 块中的语句而不是尝试,因为它可能会使可关闭的语句保持未关闭状态。
if (condition1)
prepStat = connection.prepareStatement("some SQL stuff");
result = prepStat.executeQuery();
// Another use of result
prepStat.close(); //close the statement
if (condition2)
prepStat = connection.prepareStatement("some SQL stuff");
else
prepStat = connection.prepareStatement("some SQL stuff");
result = prepStat.executeQuery();
// Use of result
result.close();
prepStat.close();
【讨论】:
以上是关于PreparedStatement 中的 Java 资源泄漏的主要内容,如果未能解决你的问题,请参考以下文章
PreparedStatement 中的 Java 资源泄漏
PreparedStatement 不适用于 Java 中的 Sybase IQ
Java -- JDBC 学习--PreparedStatement