由于并不能像Java程序那样做到自我管理内存和垃圾回收,所以我们在使用数据库资源的时候,要手动管理这这些资源的使用和释放。如果我们使用了一些资源,却并没有释放,数据库资源会一直被占用,在数据量大的时候,就会把我们的程序拖垮。这就要求我们在写相关程序的时候,当我们使用完一个资源的时候,就要主动的去把它释放掉。
那么数据库都有哪些资源需要我们去手动管理呢?主要有3个,Connection、Statement、ResultSet,这三类资源在使用完毕后就应该关闭掉,否则就会报ORA-00604 及ORA-01000 这样的错误。
还有要注意的是,要注意代码异常可能导致这些资源无法释放,所以这些资源的释放代码需要放到finally{ }的代码块里。
问题一:
Connection、Statement和ResulSet?这三个对象是在方法内部定义的,则这三个对象不是在方法执行完毕就消失了么,为什么还要单独去关闭它们呢?
解答:
这个连接是与数据库服务器的一个连接,虽然你的方法结束了,但是这个资源依然存在数据库连接并没有释放
问题二:
为什么在JDBC对数据库访问结束后,要按先关闭ResultSet,然后关闭PreparedStatement,最后关闭Connection,直接关闭Connection不就行了吗?
解答:
- 感觉上好像是只要把connection给关闭了,系统就能正常运行了。 那在查询或是其它操作中,如果只关闭Connection,不作ResultSet 和 Statement 的关闭的话,对系统性能是否会有影响呢。或者是其它实方面的不良影响。
如果你不使用连接池,那么就没有什么问题,一旦Connection关闭,数据库物理连接就被释放,所有相关Java资源也可以被GC回收了。 但是如果你使用连接池,那么请注意,Connection关闭并不是物理关闭,只是归还连接池,所以PreparedStatement和ResultSet都被持有,并且实际占用相关的数据库的游标资源,在这种情况下,只要长期运行,往往就会报“游标超出数据库允许的最大值”的错误,导致程序无法正 常访问数据库 - 因为你打开的时候有顺序,
打开时:Connection -> PreparedStatement -> ResultSet
关闭时:ResultSet-> PreparedStatement -> Connection
这个就像栈,后进先出
资源释放代码
finally {
//执行完数据库操作后记得关闭数据库连接资源
try {
resultSet.close();
preparedStatement1.close();
preparedStatement2.close();
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}