我最近剛到那裏我遇到了很多這種性質的代碼的項目後 - (這是使用JDBC Postgres的驅動程序)Statement和ResultSet緊密聯繫密切
try {
Connection conn = pool.getAConnection(); //home-grown conn pool
PreparedStatement ps = ..;
ResultSet rs = ..;
rs = ps.executeQuery();
...
} catch (SQLException se) {
conn.close();
} finally {
if (stmt != null) stmt.close();
if (rs != null) rs.close();
}
顯然,這個代碼有已經投入生產了一段時間,沒有引起任何問題。
我發現了什麼難以理解的是,在異常流量,連接被關閉或返回到池中第一;然後試圖關閉語句和結果集。父連接對象關閉後執行此操作是否合理?
的因爲代碼的結構方式,連接釋放在異常塊工作要做。這是不能改變的。 話雖這麼說,是不是好離開stmt.close()和rs.close()在最後連接後已被釋放的池?
爲了進一步澄清,如果我的理解是正確的(即,Statement和ResultSet必須連接緊密,而不是後關閉前),我需要重複catch和finally之間的一些代碼。修改後的代碼如下所示。這可以簡化嗎?
try {
...
} catch(Exception ex){
if (rs != null) {
close(rs); rs = null; // close() method impl just calls rs.close() in try-catch block
}
if (ps != null) {
close(ps); ps = null;
}
processException(ex, con); // This method logs and then either closes the connection or releases to pool, depending on some conditions.
con = null;
} finally {
if (rs != null) {
close(rs);
}
if (ps != null) {
close(ps);
}
if (null != con) {
close(con);
}
}
只爲視角,這段代碼是全 - 至少100種左右的方法!如果可能,我想進一步簡化。 感謝您的反饋。
謝謝您的回覆。同意,我總是最後關閉語句和結果集。我在這裏試圖解決的問題(也許我沒有清楚地說明) - 在上面的代碼中,連接在catch子句中關閉,最後是語句和resultset - 順序似乎不合邏輯。可以這樣離開嗎?運行此代碼沒有任何問題,但我不相信它將來不會。在代碼庫中有很多這樣的實例,這就是爲什麼我不願意將所有這些都改變,除非花費的時間是合理的。 – seattledev 2012-08-01 17:04:29
在發佈的代碼的第一部分中,只有在發生異常時纔會關閉連接。無論是否發生異常,一旦完成工作,它將更好地釋放連接。達到這個目標的最佳地點將是'finally'塊。 來到你的第二段代碼,爲什麼要在'catch'和'finally'塊中寫同一段代碼來關閉'resultset'和'preparedstatement'。無論如何,這是多餘的。只是把它作爲你的'finally'邏輯的一部分 – Sujay 2012-08-02 03:17:54
沒錯,但這是我必須使用的遺留代碼的一個限制 - 關閉/釋放連接必須留在catch子句中。我所要做的就是釋放資源。由於連接是在catch子句中釋放的,因此我試圖在連接關閉之前關閉並釋放語句和結果集。它的混亂,但我不知道如果在連接關閉後最終這樣做是正確的。 – seattledev 2012-08-02 22:10:13