Java,ResultSet.close(),PreparedStatement.close() - 为什么?

Ibo*_*lit 7 java database memory-leaks connection-leaks

在我的网络应用程序中,我广泛使用数据库.

我有一个抽象的servlet,需要数据库连接的所有servlet都可以继承.该抽象servlet创建数据库连接,调用抽象方法,该方法必须由继承的servlet覆盖以执行其逻辑,然后关闭连接.我不使用连接池,因为我的应用程序将拥有非常有限的用户和操作.

我的问题是,如果我没有关闭我的继承servlet创建的ResultSets,PreparedStatements和Statements,如果Connection创建它们的s总是关闭的话,那么最糟糕的情况是什么?

Tom*_*son 9

Statement#close()的javadoc 说:

注意:关闭Statement对象时,其当前ResultSet对象(如果存在)也将关闭.

因此,只要您始终及时关闭语句,就不必担心关闭ResultSet.

Connection#close()的javadoc 没有相应的保证,但确实说:

立即释放此Connection对象的数据库和JDBC资源,而不是等待它们自动释放.

您可以合理地解释为暗示任何陈述将被关闭.看一下开源的jTDS驱动程序,并窥探一个众所周知且昂贵的商业数据库的驱动程序,我可以看到它们正是这样做的.


gab*_*uzo 5

我很确定关闭连接会关闭相关的语句,结果集和其他相关对象.但是,所有这些都将消耗客户端上的资源,并且可能在数据库服务器上,直到连接关闭.

如果你的情况,你知道你将关闭连接真的很快你可能不虽然我不认为这应该被看作是一个最好的做法做风险太大.

但是,这仅在您当前的设置中有效.如果您的应用程序发生变化,您可能会遇到问题,因为您没有关闭语句和结果集.

虽然您不想使用连接池,但我认为即使用户/操作很少也是一个坏主意,因为打开数据库连接并不便宜.因此,即使在您的上下文中,连接池也可能有助于提高系统的响应速度.

只是关于垃圾收集的说明.关闭连接之前,使用的语句或结果集可能是GCed.但是,当涉及释放系统资源(如文件或更普遍的非Java资源(例如数据库服务器上的游标))时,不应依赖JVM GC.例如,如果您的客户端应用程序打开了很多ResultSet但只使用了分配的堆内存的一小部分,那么当数据库服务器被打开的游标窒息时,GC将永远不会启动.