jdbc资源的回收问题!

我们使用连接池访问数据库,是不是在关闭了connection之后它所属的statement和result都会自动关闭了呢?就是说只需要关闭connection?
那么这样的话是不是只要在try{...}catch{...}finnally{conn.close();}这样的框架下工作就肯定是不会存在连接资源占用的情况了呢?
经过我在DB2上测试的情况是这样的,不知道是不是不同的jdk或者as环境下会有所不同? 我一直无法完全肯定这一问题,请大家赐教!

本来我只要养成在关闭connection之前把其他对象一一关闭的习惯,就不会存在这个问题了,但是我为了偷懒起见,把简单的查询和更新操作封装到了一个基类的公用函数中,方便随时在代码中调用,代码如下:
public static ResultSet sysSelect(Connection conn,String sql)throws SQLException{
Statement st = null;
st = conn.createStatement();
return st.executeQuery(sql);
}
由于这样的功能随时随地会被使用,这不得不使我考虑这个函数中产生中间对象statement st的生存期问题!*_*

帮你顶,我也想知道清楚

是,最起码数据库端资源是得到了释放
不过这也不绝对,因为statement,result对应的是curior,而有些
DB的curior是share的,
总之,关了connection就可以了

你是说:在有的时候就算是释放了connection也可能有部分的Statement和ResultSet还占用着数据库资源?
如果是这样的话,那么在这个时候java和数据库的连接虽然断开了,可由于没有在连接的时候预先释放这些Statement和ResultSret资源(在数据库方应该理解为游标或者其他资源),会影响数据库的性能的吧?这似乎无以从程序上来证实!

关注,我对这个问题也一直搞不清楚!

> 你是说:在有的时候就算是释放了connection也可能有部分的
> tatement和ResultSet还占用着数据库资源?
不会,本地的statement和ResultSet会被回收,但数据库端的资源不一定会释放,但你不必担心此事,应为这不是一件坏事,就像你用的数据库连接池,数据库也可以对curior做cache,毕竟频繁创建curior对DB来说是比较expansive的.
当然,前提是数据库share_curior参数的设置不是0

本地对象如果不被使用的确可以释放,但tcp连接什么时候释放是个问题,还有tcp连接和connection对应还是和resultset对应,这个似乎是未知的,不过看起来java里似乎是和connection对应的,否则只需要全局维护一个长连接connection对象就可以了,只考虑生成(是否可用)的问题而不用考虑关闭的问题(除非出于性能目的,可以考虑多连接加锁的实现,也无需用户去关闭),ado里面好像可以这么做。如果tcp连接过多,一定会把数据库拖垮的。

至于conn, rs, st之间的依赖关系似乎也不明确,所以我在这个时候是自己写一个resultset接口的实现,然后重载close方法,去一一关闭其依赖对象,甚至你可以在final函数里面关闭,不过后者看起来没什么大用。

Statement也要Close,本人在使用中发现,若单单调用Connection.Close,实际上Connection并不会立即Close,可能要等到垃圾回收Statement后Connection才会Close, 本人使用的数据库是SQLServer.

我曾试过将Connection对象作为一个static属性放在一个类DBConnection中,然后,建立一个连接后,其它所有要用连接的地方就调用
DBConnection.connection,
最后再关掉,本以为这是一高招,但结果却是不可行。connection被用一次后,调用DBConnection.connection时就不行了。
但我认为思路应该是对的,不知是否还有同志尝试过

至于statement,要关掉并不难,可以在一个要连某个数据库的类中将其可connection一同声明为static,这样在任何地方用完后,就可以很方便的关掉了

全部都要关闭,关闭connection后statement和result还是可以用的,可以在关闭connection后,再试试遍历result还是可以得到数据的,result不关闭会导致游标超出范围等错误

请问navyzhu和rtm: 你们是在什么数据库上测试得到的这个结果的?
我在DB2和ORACLE8.1.2上测试出来的结果都很明显地提示:SQLException:关闭的连接....(所有的conn,st,rs使用的时候是默认方式)

这么看来odbc/jdbc的设计现在也不太适宜了,为什么有conn, st的存在是因为希望可以复用,减少开销,但增加了程序员的负担,可能不多的几行代码,建立对象和关闭对象占了一半。甚至复用也很难实现,因为很多页面中可能只访问一两次数据库,如果没有自己设计或者底层的连接池,页面切换该消耗的还是要消耗。就算不是这样,按照设计的一般标准,需要把粒度细化,这样结果和上面一样,如果要重用,必须附加上多余的耦合变量,更加不好。
反过来有了连接池,也基本上不需要conn,或者st,后者根据使用者的经验,似乎可以表达为得到rs后就可以关闭或者直接重用。conn也是可以重用的(否则也就不能连接池了),不过大概需要在前一个返回的resultset被关闭之后,也就是我说的和tcp连接对应的概念,这个和ado不同。

Connection一旦关闭,所有由它打开的ResultSet不在可用。这在jdk文档中有说明。否则,没有必要定义javax.sql.RowSet了。

我用的数据库是SQLServer2000,程序是一个数据月结程序,开始我发现月结有时成功,有时失败,看了后台才发现因为Statement没有Close,所以Connection太多以至于打开几百个Connection,结果处理失败。

Statement,ResultSet肯定都是关闭了得,但是资源还没有释放阿。如果从性能方面考虑的话,一定的明显的关闭Statement,ResultSet,还有两点需要注意:
1,不要隐式产生Statement,ResultSet对象
2,关闭对象一定要在finally中关闭