2010-11-17 229 views
9

我有一個使用JDBC連接到MySQL的應用程序。在某些情況下,JDBC連接處於空閒狀態幾個小時(甚至可能是幾天),並且它失去了與MySQL的連接,然後除非它試圖執行查詢。什麼是最好的解決方案?使用JDBC連接到MySQL

回答

15

保持連接打開的時間是一個不好的做法。數據庫在打開很長一段時間後會強制關閉。您應該編寫JDBC代碼,以便始終關閉與您已獲取它們的塊相同的finally塊中的連接(以及語句和結果集),以防止資源泄漏。

但是,獲取每個打嗝的連接確實是一項相當昂貴的任務,因此您希望使用連接池的。體面連接池將自行管理打開,測試,重用和關閉連接。然而,這並不意味着你可以改變你的JDBC代碼,永不關閉它們。您仍然需要關閉它們,因爲這實際上會將底層連接釋放回池以備將來重用。

有幾個連接池,像Apache DBCP這是單線程,因此在性能差,C3P0這是多線程和性能更好,併爲Tomcat JDBC您使用Tomcat和不希望使用內置的DBCP的情況下由於表現不佳。

可以通過編程創建連接池,在這裏與C3P0一個例子:

ComboPooledDataSource dataSource = new ComboPooledDataSource(); 
dataSource.setDriverClass("com.mysql.jdbc.Driver"); 
dataSource.setJdbcUrl("jdbc:mysql://localhost:3306/dbname"); 
dataSource.setUser("username"); 
dataSource.setPassword("password"); 

在應用程序的啓動做一次,然後就可以按如下方式使用它:

Connection connection = null; 
// ... 

try { 
    connection = dataSource.getConnection(); 
    // ... 
} finally { 
    // ... 
    if (connection != null) try { connection.close(); } catch (SQLException ignore) {} 
} 

當你運行在像servlet容器(例如Tomcat)的支持JNDI的容器中,那麼您也可以聲明它爲java.sql.DataSource(Tomcat特定手冊here)。然後它將使用servletcontainer提供的連接池設施。然後您可以按如下方式獲取數據源:

DataSource dataSource = (DataSource) new InitialContext().lookup("java:comp/env/jdbc/YourDataSourceName"); 
+0

爲什麼不把連接保持爲類成員,檢查它是否在計劃使用時關閉,並在關閉時啓動新連接?除了保持一段時間的記憶之外,這會有什麼問題呢? – 2015-10-06 06:32:09

+2

@EB:這是絲毫不安全的。相關:http://stackoverflow.com/q/9428573您應該爲每個線程和事務使用一個完全獨立的連接。他們可以保持開放並在完成線程本地事務作業後重用,但這已經正是連接池的功能。連接池並沒有在物理上關閉連接,它只是保持打開並在釋放之前對其進行測試(正如本文中已經回答的那樣) – BalusC 2015-10-06 06:33:36

4

有庫,如Apache's DBCP可以做連接池。其中一部分是它們可以設置爲在您使用它時自動測試連接(例如「SELECT NOW()FROM DUAL」或其他無害),並在必要時自動重新建立連接,從而允許您應用程序假裝連接是永久的。

+0

這是要走的路。您甚至可以在將連接返回給客戶端之前將其設置爲執行一個虛擬SELECT,以便您知道它會起作用。 – 2010-11-17 22:18:43