MySQL+Hibernate下鏈接空閒8小時自動斷開問題解決

本文爲轉載學習html

轉載文章1:http://hi.baidu.com/boyyf/item/fe4dcc1329297349e75e06cejava

    前段時間剛完成一個家教網項目,數據庫爲MySQL5.0,持久層使用Hibernate 3.1,沒有使用額外的鏈接池,那麼Hibernate會默認使用它自帶的一個默認鏈接池,也就是DriverManagerConnectionProvidermysql

  先在本機上調試都毫無問題,因而部署到服務器上,也都沒什麼問題。因爲這是新網站,根本還沒正式對外發布和宣傳,因此頭兩天根本沒人訪問。等到次日,我再次訪問網站時,問題就出現了,錯誤信息以下:sql

javax.servlet.ServletException: org.hibernate.exception.JDBCConnectionException: could not execute query org.apache.struts.action.RequestProcessor.processException(RequestProcessor.java:535) .........數據庫

org.hibernate.exception.JDBCConnectionException: could not execute query org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:74) ...........apache

    當時也搞不清楚爲何,但重啓Tomcat後就一切回覆正常了,可是又過了一天,問題再次出現。仔細分析錯誤信息,問題確定出在數據庫鏈接部分,在網上查閱大量信息後,明確了問題的緣由:MySQL對全部鏈接的有效時間默認爲28800秒,正好8小時,也就是說,若是一個鏈接8小時沒有請求和操做,就會自動斷開;可是對於Hibernate來講,它的鏈接池並不知道它所管理的鏈接中是否有被MySQL斷開的若是一個程序要使用數據庫鏈接,而Hibernte的鏈接池分配一個已經被MySQL斷開了的給程序使用,那麼便會出現錯誤tomcat

    爲了證明確實是這個錯誤,我在本機上作了以下測試:首先啓動Tomcat,網站可以正常打開;而後修改系統時間,日後調1天;而後再打開網站,一樣的問題果真出現!MySQL + Hibernate架構至關廣泛,因此這個問題也至關廣泛,若讀者也有這樣的項目,建議作一下一樣的測試,看看是否存在此問題!服務器

  問題找到了,怎麼解決呢?session

  思路1:增大MySQL的鏈接有效時間;架構

  思路2:從程序自身出發,修改鏈接池的相關參數。

  顯然,思路1是不可行的,一方面這個思路不可能保證這個問題絕對的解決,若是無訪問時間夠長,仍是大於MySQL的鏈接有效時間,問題一樣會發生;另外一方面,通常狀況下,咱們都是將程序部署在別人服務器上,咱們不可能去修改MySQL配置。那麼只能從思路2入手了。

經查資料發現,Hibernate支持以下的鏈接池:

   DriverManagerConnectionProvider:表明由Hibernate提供的默認的數據庫鏈接池

   C3P0ConnectionProvider:表明C3P0鏈接池

   ProxoolConnectionProvider:表明Proxool鏈接池

   DBCPConnectionProvider:表明DBCP鏈接池

   DatasourceConnectionProvider:表明在受管理環境中由容器提供的數據源

  其中,默認鏈接池並不支持在分配一個鏈接時,測試其有效與否的功能,而C3P0、Proxool、DBCP都提供了這樣的功能,正好能夠解決上述問題。綜合考慮各個鏈接池的效率、穩定性、易用性,決定換用Proxool,它確實在各方面表現優良,方便配置。

  下面就看看如何配置Proxool:

一、Hibernate配置文件:

<session-factory>

<property name="hibernate.connection.provider_class">org.hibernate.connection.ProxoolConnectionProvider</property>

<property name="hibernate.proxool.xml">proxool.xml</property>

<property name="hibernate.proxool.pool_alias">mysql</property>

<property name="show_sql">false</property>

<property name="dialect">org.hibernate.dialect.MySQLDialect</property>

<mapping resource="com/lab1000/jcom/pojo/Admin.hbm.xml" />

...

</session-factory>

  其中各屬性含義以下:

hibernate.connection.provider_class:指明使用Proxool鏈接池

hibernate.proxool.xml:指明Proxool配置文件所在位置,這裏與Hibernate的配置文件在同一目錄下

hibernate.proxool.pool_alias:指明要使用的proxool.xml中定義的proxool別名。

二、Proxool配置文件(proxool.xml):

<?xml version="1.0" encoding="UTF-8"?> 

<!-- the proxool configuration can be embedded within your own application's. 

Anything outside the "proxool" tag is ignored. --> 

<something-else-entirely> 

<proxool>

<!-- proxool別名 -->

<alias>mysql</alias>

<!-- 數據庫鏈接Url -->

<driver-url> 

jdbc:mysql://localhost/yourDatebase?useUnicode=true&characterEncoding=UTF-8

</driver-url>

<!-- JDBC驅動名稱 -->

<driver-class>com.mysql.jdbc.Driver</driver-class>

<!-- 數據庫鏈接賬號 -->

<driver-properties> 

<property name="user" value="root" /> 

<property name="password" value="password" />

</driver-properties>

<!-- proxool自動偵察各個鏈接狀態的時間間隔(毫秒),偵察到空閒的鏈接就立刻回收,超時的銷燬 -->

<house-keeping-sleep-time>90000</house-keeping-sleep-time>

<!-- 指因未有空閒鏈接能夠分配而在隊列中等候的最大請求數,超過這個請求數的用戶鏈接就不會被接受 --> 

<maximum-new-connections>20</maximum-new-connections>

<!-- 最少保持的空閒鏈接數 -->

<prototype-count>3</prototype-count>

<!-- 容許最大鏈接數,超過了這個鏈接,再有請求時,就排在隊列中等候,最大的等待請求數由maximum-new-connections決定 -->

<maximum-connection-count>20</maximum-connection-count>

<!-- 最小鏈接數 -->

<minimum-connection-count>3</minimum-connection-count>

<!-- 在分配鏈接先後是否進行有效性測試,這個是解決本問題的關鍵 -->

<test-before-use>true</test-before-use>

<test-after-use>true</test-after-use>

<!-- 用於測試的SQL語句 -->

<house-keeping-test-sql>SELECT CURRENT_USER</house-keeping-test-sql>

</proxool> 

</something-else-entirely>

三、下載和安裝Proxool的包文件

  下載地址:http://proxool.sourceforge.net/download.html

  下載後並解壓後,將其中lib文件夾下的jar文件拷貝到你站點的WEB-INF/lib下

  自此,Proxool配置成功。從新啓動Tomcat,再次作上述測試,問題解決。


轉載文章2:http://blog.csdn.net/lip8654/article/details/2121387

    新開發的一個網站,天天早上來開就有訪問數據庫的操做就出現異常,數據庫爲Mysql。也就是說在運行中每一個一段長的空閒時間就出現異常:

    查看了Mysql的文檔,以及Connector/J的文檔以及在線說明發現,出現這種異常的緣由是:Mysql服務器默認的「wait_timeout」是8小時,也就是說一個connection空閒超過8個小時,Mysql將自動斷開該 connection。這就是問題的所在,在C3P0 pools中的connections若是空閒超過8小時,Mysql將其斷開,而C3P0並不知道該connection已經失效,若是這時有 Client請求connection,C3P0將該失效的Connection提供給Client,將會形成上面的異常。

解決的方法有3種:

1.增長wait_timeout的時間。

2.減小Connection pools中connection的lifetime。

3.測試Connection pools中connection的有效性。

固然最好的辦法是同時綜合使用上述3種方法,下面就對hibernate使用C3P0分別作一說明,假設wait_timeout爲默認的8小時

Hibernate使用C3P0的鏈接池,並隊c3p0配置。

1.導入c3p0.jar包,hibernate自帶的包,也能夠在網上下載一個。

2.Hibernate的配置文件,hibernate.cfg.xml中增長:

<property name="c3p0.acquire_increment">1</property>

              <property name="c3p0.idle_test_period">100</property>

              <property name="c3p0.max_size">5</property>

<property name="c3p0.max_statements">0</property>

              <property name="c3p0.min_size">2</property>

              <property name="c3p0.timeout">90</property>

              <property name="c3p0.preferredTestQuery ">select 1 from user where id=1</property>

              <property name="c3p0.idleConnectionTestPeriod ">18000</property>           

<property name="c3p0.maxIdleTime">25000</property>        

<property name="c3p0.testConnectionOnCheckout">true</property>

3.從新啓動tomcat,問題解決。

相關文章
相關標籤/搜索