本文爲轉載學習html
轉載文章1:http://hi.baidu.com/boyyf/item/fe4dcc1329297349e75e06cejava
前段時間剛完成一個家教網項目,數據庫爲MySQL5.0,持久層使用Hibernate 3.1,沒有使用額外的鏈接池,那麼Hibernate會默認使用它自帶的一個默認鏈接池,也就是DriverManagerConnectionProvider。mysql
先在本機上調試都毫無問題,因而部署到服務器上,也都沒什麼問題。因爲這是新網站,根本還沒正式對外發布和宣傳,因此頭兩天根本沒人訪問。等到次日,我再次訪問網站時,問題就出現了,錯誤信息以下: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,問題解決。