我們今天主要描述Hibernate用MySQL數據庫時鏈接關閉異常的實際解決方案,願在你學習Hibernate用MySQL數據庫時鏈接關閉異常的實際解決方案中以起到拋磚引玉的作用,以下就是文章的詳細內容介紹,望大家借鑒。
在一個項目中,客戶要求除操作系統外全部使用免費軟件,因此我使用了MySQL 4.0作為MySQL數據庫服務器,其JDBC驅動為3.0.9版本,在給客戶安裝後調試一切正常。可是到了第二天,只要一登錄就提示“No operations allowed after connection closed”異常,顯示在浏覽器上。在經過一番檢查後我發現,在這種情況下只要重新啟動Tomcat就恢復正常,然而到了第二天問題依舊。
在網上查找一下,原來MySQL在經過8小時不使用後會自動關閉已打開的連接,摘錄原文如下:
5.4. I have a servlet/application that works fine for a day, and then stops working overnight
MySQL closes connections after 8 hours of inactivity. You either need to use a connection pool that handles stale connections or use the "autoReconnect" parameter (see "Developing Applications with MySQL Connector/J").
Also, you should be catching SQLExceptions in your application and dealing with them, rather than propagating them all the way until your application exits, this is just good programming practice. MySQL Connector/J will set the SQLState (see java.sql.SQLException.getSQLState() in your APIDOCS) to "08S01" when it encounters network-connectivity issues during the processing of a query. Your application code should then attempt to re-connect to MySQL at this point.
在客戶那邊,晚上時間是不會有人使用這個系統的,就造成了系統中原先沒有考慮到的這個情況。
為此我試驗了三種方法:
1、在MySQL數據庫的url中加入autoReconnect=true
2、在每次調用getSession()方法時判斷session.isClosed()是否為真,若為真則調用session.reconnect();
3、在經過兩天,事實證明前兩種方法都不起作用的情況下,我在這個頁面找到了第三種方法,即不使用Hibernate內置的連接池Hibernate強烈推薦不使用但我以前一直在用),改用C3P0連接池,這個連接池會自動處理MySQL數據庫連接被關閉的情況。要使用C3P0很簡單,先從Hibernate裡把c3p0-0.8.3.jar復制到項目的lib目錄中,再在hibernate.properties裡去掉hibernate.c3p0開頭的那些屬性的注釋使用缺省值或自己需要的數值),這樣Hibernate就會自動使用C3P0代替內置的連接池了。到目前為止前面的問題沒有再出現過。
以前對Hibernate警告不要使用內置連接池作產品用途沒有太放在心上,這次是一個教訓,所以不論從穩定還是性能的考慮,都應該選擇相對更加成熟的連接池。
update:除了連接池的原因,原先寫的HibernateDAO類也有問題,在有些情況下一個session會被多個請求反復使用,現在已改正。另外,c3p0這個名字不是星球大戰裡那個機器人麼?