JDBC數據庫連接池connection關閉後Statement和ResultSet未關閉的問題

本文轉自:http://k1121.iteye.com/blog/1279063


(1)    主要問題


針對關閉connection是否會自動關閉Statement和ResultSet的問題,以及Statement和ResultSet所佔用資源是否會自動釋放問題,JDBC處理規範或JDK規範中做了如下描述:

JDBC處理規範

JDBC. 3.0 Specification——13.1.3 Closing Statement Objects

An applicationcalls the method Statement.close to indicate that it has finished processing astatement. All Statement objects will be closed when the connection thatcreated them is closed. However, it is good coding practice for applications toclose statements as soon as they have finished processing them. This allows anyexternal resources that the statement is using to be released immediately.

Closing aStatement object will close and invalidate any instances of ResultSet producedby that Statement object. The resources held by the ResultSet object may not bereleased until garbage collection runs again, so it is a good practice toexplicitly close ResultSet objects when they are no longer needed.

These commentsabout closing Statement objects apply to PreparedStatement and CallableStatementobjects as well.

JDBC. 4.0 Specification——13.1.4 Closing Statement Objects

An applicationcalls the method Statement.close to indicate that it has finished processing astatement. All Statement objects will be closed when the connection that createdthem is closed. However, it is good coding practice for applications to closestatements as soon as they have finished processing them. This allows any externalresources that the statement is using to be released immediately.

Closing aStatement object will close and invalidate any instances of ResultSet producedby that Statement object. The resources held by the ResultSet object may not bereleased until garbage collection runs again, so it is a good practice to explicitlyclose ResultSet objects when they are no longer needed.

Once aStatement has been closed, any attempt to access any of its methods with theexception of the isClosed or close methods will result in a SQLException beingthrown.

These commentsabout closing Statement objects apply to PreparedStatement andCallableStatement objects as well.

規範說明:connection.close 自動關閉 Statement.close 自動導致 ResultSet 對象無效(注意只是 ResultSet 對象無效,ResultSet 所佔用的資源可能還沒有釋放)。所以還是應該顯式執行connection、Statement、ResultSet的close方法。特別是在使用connection pool的時候,connection.close 並不會導致物理連接的關閉,不執行ResultSet的close可能會導致更多的資源泄露。

JDK處理規範:

JDK1.4

Note: A ResultSet object is automatically closed by theStatement object that generated it when that Statement object is closed,re-executed, or is used to retrieve the next result from a sequence of multipleresults. A ResultSet object is also automatically closed when it is garbagecollected.

Note: A Statement object is automatically closed when it isgarbage collected. When a Statement object is closed, its current ResultSetobject, if one exists, is also closed.

Note: A Connection object isautomatically closed when it is garbage collected. Certain fatal errors alsoclose a Connection object.

JDK1.5

Releases this ResultSet object'sdatabase and JDBC resources immediately instead of waiting for this to happenwhen it is automatically closed.

Note: A ResultSet object isautomatically closed by the Statement object that generated it when thatStatement object is closed, re-executed, or is used to retrieve the next resultfrom a sequence of multiple results. A ResultSet object is also automaticallyclosed when it is garbage collected.

規範說明:

1.垃圾回收機制可以自動關閉它們;

2.Statement關閉會導致ResultSet關閉;

3.Connection關閉不一定會導致Statement關閉。


V6使用的是數據庫連接池,Connection關閉並不是物理關閉,只是歸還連接池,所以Statement和ResultSet有可能被持有,並且實際佔用相關的數據庫的遊標資源,在這種情況下,只要長期運行就有可能報“遊標超出數據庫允許的最大值”的錯誤,導致程序無法正常訪問數據庫。

(2)    解決建議

(1)      由於垃圾回收的線程級別是最低的,爲了充分利用數據庫資源,有必要顯式關閉它們,尤其是使用Connection Pool的時候;

(2)      最優經驗是按照ResultSet,Statement,Connection的順序執行close;

(3)      爲了避免由於java代碼有問題導致內存泄露,需要在rs.close()和stmt.close()後面一定要加上rs = null和stmt = null;

(4)      如果一定要傳遞ResultSet,應該使用RowSet,RowSet可以不依賴於Connection和Statement。Java傳遞的是引用,所以如果傳遞ResultSet,你會不知道Statement和Connection何時關閉,不知道ResultSet何時有效。
發佈了385 篇原創文章 · 獲贊 25 · 訪問量 200萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章