Java 结果集未正确关闭



我有一个Java应用程序,其中包含许多代码片段,如下所示。 非常简单的 Oracle 数据库查询。 返回并解析有效数据,然后调用 close() 函数。

ResultSet rs = null;
Statement stmt = null;
try
{
stmt = conn.createStatement();
rs = stmt.executeQuery("SELECT * FROM example");
while (rs.next())
{
// do stuff
}
rs.close();
stmt.close();
System.out.println("test1");
}
catch (Exception e)
{
System.out.println("error1");
}

我开始遇到"超出最大游标数"错误。 我检查了我的方法以确定结果集是否未关闭。catch子句从未被触发,并且每次都打印"test1"。 这意味着 rs.close() 和 stmt.close() 行不会被跳过。 然而,结果集实际上并没有被关闭。

我添加了一个finally条款,它解决了这个问题。

finally
{
if (rs != null)
{
try
{
rs.close();
System.out.println("test2");
}
catch (Exception e)
{
System.out.println("error2");
}
}
if (stmt != null)
{
try
{
stmt.close();
System.out.println("test3");
}
catch (Exception e)
{
System.out.println("error3");
}
}
}

输出:

test1
test2
test3

我的问题是,为什么rs.close()和stmt.close()需要调用两次try子句中的调用似乎没有任何作用。 然而,我在finally条款中再次称呼他们,他们成功了。 这怎么可能?

Use try-with-resources (Java 7+):

try (Statement stmt = conn.createStatement()) {
try (ResultSet rs = stmt.executeQuery("SELECT * FROM example")) {
while (rs.next()) {
// do stuff
}
System.out.println("test1");
}
} catch (Exception e) {
System.out.println("error1");
}

不,无需调用两次

不,在 JDBC 中没有必要调用close两次。我怀疑还有其他事情发生。

我们无法确定您的代码中发生了什么。我们无法知道您所谓的第二个电话是否真的解决了问题。例如,Statement::close的文档说:

对已关闭的语句对象调用方法 close 不起作用。

试用资源

正如Andreas的答案所建议的那样,您应该使用资源尝试。

看:

  • Java 7 关于试用资源的技术说明。
  • 甲骨文教程。
  • Java 9 增强了对资源的尝试,使用以前在 Try-with-Resource 语句中创建的变量。

对 JDBC 以及任何实现资源的资源AutoCloseable使用试用资源。

您可以将一个或多个资源放入try( … )中。用分号分隔,最后一个分号是可选的。Java将跟踪资源,每个资源都以与打开相反的顺序关闭。如果中间发生异常,Java 知道不要尝试关闭空资源对象。这大大简化了您的编码。

相关内容

  • 没有找到相关文章

最新更新