java 关闭jdbc_java - 必须单独关闭JDBC结果集和语句,尽管之后Connection已关闭?...

java - 必须单独关闭JDBC结果集和语句,尽管之后Connection已关闭?

据说在使用后关闭所有JDBC资源是一个好习惯。 但是,如果我有以下代码,是否有必要关闭Resultset和Statement?

Connection conn = null;

PreparedStatement stmt = null;

ResultSet rs = null;

try {

conn = // Retrieve connection

stmt = conn.prepareStatement(// Some SQL);

rs = stmt.executeQuery();

} catch(Exception e) {

// Error Handling

} finally {

try { if (rs != null) rs.close(); } catch (Exception e) {};

try { if (stmt != null) stmt.close(); } catch (Exception e) {};

try { if (conn != null) conn.close(); } catch (Exception e) {};

}

问题是连接的关闭是否完成了工作,或者是否使用了一些资源。

Zeemee asked 2019-03-06T06:48:24Z

8个解决方案

168 votes

你所做的是完美和非常好的练习。

我说它的良好做法的原因...例如,如果由于某种原因你使用“原始”类型的数据库池并且你调用connection.close(),连接将返回到池,ResultSet/Statement将永远不会关闭 然后你会遇到很多不同的新问题!

所以你不能总是依靠connection.close()来清理。

我希望这有帮助 :)

Paul answered 2019-03-06T06:48:56Z

98 votes

借助try-with-resources语句,Java 1.7让我们的生活更加轻松。

try (Connection connection = dataSource.getConnection();

Statement statement = connection.createStatement()) {

try (ResultSet resultSet = statement.executeQuery("some query")) {

// Do stuff with the result set.

}

try (ResultSet resultSet = statement.executeQuery("some query")) {

// Do more stuff with the second result set.

}

}

这种语法非常简洁和优雅。 即使无法创建statement,connection也将关闭。

Raúl Salinas-Monteagudo answered 2019-03-06T06:49:34Z

60 votes

来自javadocs:

当一个closeQuietly对象关闭时,它   目前Statements对象,如果一个   存在,也是关闭的。

但是,关闭closeQuietly和Statements关闭底层Connections时,javadocs不是很清楚。它们只是声明关闭连接:

发布此closeQuietly对象   数据库和JDBC资源   马上而不是等待   它们会被自动释放。

在我看来,当你完成它们时,总是明确关闭closeQuietly,Statements和Connections,因为close的实现可能因数据库驱动程序而异。

您可以使用Apache的DBUtils中的方法(例如closeQuietly)为自己节省大量的样板代码。

dogbane answered 2019-03-06T06:50:54Z

31 votes

我现在正在使用Oracle和Java。 在这里我的观点:

您应该明确关闭ResultSet.close();和ResultSet,因为Oracle以前在关闭连接后保持游标保持打开存在问题。 如果不关闭Statement(光标),则会抛出超出最大打开游标的错误。

我想您可能会遇到与您使用的其他数据库相同的问题。

完成后,这是教程Close ResultSet:

完成后关闭ResultSet

完成后立即关闭ResultSet.close();对象   甚至使用ResultSet对象   虽然Statement对象关闭了   ResultSet隐含的对象   关闭,明确关闭ResultSet   给垃圾收集器机会   尽早回忆记忆   因为ResultSet对象可能占用   大量内存取决于查询。

ResultSet.close();

bluish answered 2019-03-06T06:52:24Z

6 votes

如果你想要更紧凑的代码,我建议使用Apache Commons DbUtils。 在这种情况下:

Connection conn = null;

PreparedStatement stmt = null;

ResultSet rs = null;

try {

conn = // Retrieve connection

stmt = conn.prepareStatement(// Some SQL);

rs = stmt.executeQuery();

} catch(Exception e) {

// Error Handling

} finally {

DbUtils.closeQuietly(rs);

DbUtils.closeQuietly(stmt);

DbUtils.closeQuietly(conn);

}

baron5 answered 2019-03-06T06:52:56Z

2 votes

用于关闭与JDBC相关的资源的正确且安全的方法(取自如何正确关闭JDBC资源 - 每次):

Connection connection = dataSource.getConnection();

try {

Statement statement = connection.createStatement();

try {

ResultSet resultSet = statement.executeQuery("some query");

try {

// Do stuff with the result set.

} finally {

resultSet.close();

}

} finally {

statement.close();

}

} finally {

connection.close();

}

Prasanth Jayachandran answered 2019-03-06T06:53:29Z

-1 votes

使用Java 6表单我认为最好在关闭之前检查它是否已关闭(例如,如果某个连接池在其他线程中逐出连接) - 例如某些网络问题 - 语句和结果集状态可以关闭。 (它经常发生,但我在Oracle和DBCP中遇到了这个问题)。 我的模式(在较旧的Java语法中)是:

try {

...

return resp;

} finally {

if (rs != null && !rs.isClosed()) {

try {

rs.close();

} catch (Exception e2) {

log.warn("Cannot close resultset: " + e2.getMessage());

}

}

if (stmt != null && !stmt.isClosed()) {

try {

stmt.close();

} catch (Exception e2) {

log.warn("Cannot close statement " + e2.getMessage());

}

}

if (con != null && !conn.isClosed()) {

try {

con.close();

} catch (Exception e2) {

log.warn("Cannot close connection: " + e2.getMessage());

}

}

理论上它不是100%完美,因为在检查关闭状态和关闭本身之间,状态的变化有一点空间。 在最坏的情况下,你会得到一个警告。 - 但它比长期查询中状态更改的可能性要小。 我们在生产中使用这种模式,带有“avarage”负载(150同时用户),我们没有遇到任何问题 - 所以永远不要看到那个警告信息。

Csákány Róbert answered 2019-03-06T06:54:26Z

-2 votes

不,你不需要关闭任何东西,但连接。 根据JDBC规范,关闭任何更高的对象将自动关闭较低的对象。 关闭Connection将关闭连接已创建的任何ResultSet。 关闭任何Statement将关闭由该Statement创建的所有Connection.无论Connection是否可以使用都无关紧要。 即使是poolable连接也必须在返回游泳池之前进行清洁。

当然,您可能在Connection上创建了大量语句的长嵌套循环,然后关闭它们是合适的。 我几乎从不关闭ResultSet但是,当关闭Statement或Connection将关闭它们时似乎过度。

Enerccio answered 2019-03-06T06:55:21Z

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值