2012-07-31 18 views
0

我最近剛到那裏我遇到了很多這種性質的代碼的項目後 - (這是使用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種左右的方法!如果可能,我想進一步簡化。 感謝您的反饋。

回答

0

它的意義對於在finally塊被釋放連接。所以不關閉您的StatementResultSetfinally塊。

推理很簡單:確保您的StatementResultSet在成功執行和異常情況下均被關閉。連接也是如此。我就做了這樣的事情在finally

try{ 

}catch(Exception exe){ 

}finally{ 
    if (stmt != null) stmt.close(); 
    if (rs != null) rs.close(); 

    //release connection to connection pool 

} 

而且,我相信,當一個Statement被關閉,其目前ResultSet也被關閉。因此,如果rsstmt相關聯,那麼我相信它會在您執行時關閉stmt.close()

+0

謝謝您的回覆。同意,我總是最後關閉語句和結果集。我在這裏試圖解決的問題(也許我沒有清楚地說明) - 在上面的代碼中,連接在catch子句中關閉,最後是語句和resultset - 順序似乎不合邏輯。可以這樣離開嗎?運行此代碼沒有任何問題,但我不相信它將來不會。在代碼庫中有很多這樣的實例,這就是爲什麼我不願意將所有這些都改變,除非花費的時間是合理的。 – seattledev 2012-08-01 17:04:29

+1

在發佈的代碼的第一部分中,只有在發生異常時纔會關閉連接。無論是否發生異常,一旦完成工作,它將更好地釋放連接。達到這個目標的最佳地點將是'finally'塊。 來到你的第二段代碼,爲什麼要在'catch'和'finally'塊中寫同一段代碼來關閉'resultset'和'preparedstatement'。無論如何,這是多餘的。只是把它作爲你的'finally'邏輯的一部分 – Sujay 2012-08-02 03:17:54

+0

沒錯,但這是我必須使用的遺留代碼的一個限制 - 關閉/釋放連接必須留在catch子句中。我所要做的就是釋放資源。由於連接是在catch子句中釋放的,因此我試圖在連接關閉之前關閉並釋放語句和結果集。它的混亂,但我不知道如果在連接關閉後最終這樣做是正確的。 – seattledev 2012-08-02 22:10:13