2011-03-02 59 views
2

我正在審查大量現有代碼,試圖查找會導致連接池用完或拋出其他錯誤的未關閉連接。MySQL和JDBC連接池:未關閉的語句

在一些地方我看到連接返回到池,ResultSet被關閉,但PreparedStatement沒有關閉。

在僞代碼

它應該是這樣的:

Connection conn = null; 
try { 
    conn = MyJdbcTemplateHolder.getNewConnectionFromPool(); 
    PreparedStatement ps = conn.prepareStatement(sql, ...); 
    ResultSet rs = st.executeQuery(); 

    // do stuff with results 

} catch(Exception e) { 
    // exception 
} finally { 
    rs.close(); 
    MyJdbcTemplateHolder.returnConnectionToPool(conn); 
    //***** Here is what's missing: st.close(); ***** 
} 

的問題是:可以公開聲明的原因的問題,因爲它沒有明確關閉?或者正在關閉ResultSet並返回足夠的連接?

很顯然,我不是在談論一個開放的聲明 - 我們有100個連接池和數十個可能出現此問題的代碼位置。

  • MySQL的版本是5.1
  • 我的JDBC罐子使用mysql-connector-java的5.1.11-bin.jar

回答

2

答案是肯定的,它可能會導致問題。正如這裏討論的SO:

如果你與他們所做的(或在finally塊後做相反的順序不緊密連接相關的資源

),你有風險。連接池根據它們的處理方式而有所不同,但令人擔憂的是 - 至少 - 將不正確關閉的一組資源拋入池中。

在情況下,目前還不清楚(你可能已經知道這一點),資源的正確關閉是進一步討論在這裏:

注意,在即將到來的Java 7中,將有我們有所幫助:

http://www.javaspecialists.eu/archive/Issue190.html

中一種新的嘗試,與資源聲明是在Java中引入的,它會自動關閉try語句中引用的任何AutoCloseable資源。

+1

+1 - 是!簡短的回答。按照您打開它的相反順序關閉所有JDBC。永遠,永遠,永遠。如果你沒有做到這一點,這需要一個根深蒂固的習慣,足以解決它。 – rfeak 2011-03-02 16:34:40

+0

感謝kvista,我明白了,這就是我所害怕的......我認爲這個代碼會有很多工作。有沒有人知道我應該期待什麼樣的行爲,因爲未公開的陳述?或者他們在封面下發生了什麼? – Galz 2011-03-02 17:15:43

+0

我的個人經驗是數據庫沒有連接,因爲他們沒有被清理和徘徊。池會要求新的數據庫,最終數據庫將不再提供。隨着時間的推移,數據庫最終會清理連接,但速度比他們「泄露」的速度慢。 – rfeak 2011-03-02 17:40:34