tomcat7使用dbcp鏈接池遇到的坑

項目部署在tomcat後每隔一段時間便會報錯java

Cause: java.sql.SQLException: Could not retrieve transation read-only status server
; SQL []; Could not retrieve transation read-only status server; nested exception is java.sql.SQLException: Could not retrieve transation read-only status server

開始覺得是數據庫事務級別太高,後來發現是每隔一天沒操做便會丟失連接,因而找到緣由mysql

MySQL 的默認設置下,當一個鏈接的空閒時間超過8小時後,MySQL 就會斷開該鏈接,而 c3p0/dbcp 鏈接池則覺得該被斷開的鏈接依然有效。在這種狀況下,若是客戶端代碼向c3p0/dbcp 鏈接池請求鏈接的話,鏈接池就會把已經失效的鏈接返回給客戶端,客戶端在使用該失效鏈接的時候即拋出異常。

因而簡單的修改了mysql的設置web

#my.cnf
    wait_timeout=31536000  
    interactive_timeout=31536000

可是這樣改動的話wait_timeout太大了,會保留太多的無效連接,因而就從鏈接池上採起改動。在spring 鏈接池配置中加入定時檢測,配置字段以下spring

maxWait="3000" 從池中取鏈接的最大等待時間,單位ms.  
initialSize="10"  初始化鏈接  
maxIdle="60"   最大空閒鏈接  
minIdle="10"   最小空閒鏈接  
maxActive="80" 最大活動鏈接  
   
validationQuery = "SELECT 1"  驗證使用的SQL語句  
testWhileIdle = "true"      指明鏈接是否被空閒鏈接回收器(若是有)進行檢驗.若是檢測失敗,則鏈接將被從池中去除.  
testOnBorrow = "false"   借出鏈接時不要測試,不然很影響性能  
timeBetweenEvictionRunsMillis = "30000"  每30秒運行一次空閒鏈接回收器  
minEvictableIdleTimeMillis = "1800000"  池中的鏈接空閒30分鐘後被回收,,默認值就是30分鐘
numTestsPerEvictionRun="10" 在每次空閒鏈接回收器線程(若是有)運行時檢查的鏈接數量,默認值就是3.  
      
removeAbandoned="true"  鏈接泄漏回收參數,當可用鏈接數少於3個時才執行  
removeAbandonedTimeout="180"  鏈接泄漏回收參數,180秒,泄露的鏈接能夠被刪除的超時值

配置後問題獲得解決。sql

查看資料的過程當中發現dbcp鏈接池是有兩種的:Tomcat JDBC鏈接池與Apache Commons DBCP鏈接池。下面是二者的區別數據庫

1.Commons DBCP 1.x是單線程。在分配對象或對象返回的時候,會鎖定所有鏈接池。(不適用於Commons DBCP 2.x)

2.Commons DBCP 1.x在邏輯cpu數量增長或者併發縣城增長時,性能可能會變的很慢。高併發系統受到的影響會更加明顯(不適用於Commons DBCP 2.x)

3.Commons DBCP 擁有60多個類。tomcat-jdbc-pool核心只有8個類,而將來若是需求變動,那麼tomcat JDBC鏈接池會改動更少。

4.Commons DBCP使用靜態接口,須要對應的jre須要對應的DBCP 版本,不然會拋出 NoSuchMethodException異常

5.Tomcat JDBC鏈接池無需爲庫自己添加額外線程,就能獲取異步鏈接。

6.Tomcat JDBC鏈接池使用 javax.sql.PooledConnection接口獲取底層鏈接

7.Tomcat JDBC鏈接池 能夠防止飢餓。若是池變空,線程將等待一個鏈接。當鏈接返回時,池就將喚醒正確的等待線程。

配置tomcat-dbcp是在tomcat安裝路徑下配置的tomcat

配置Tomcat-DBCP
Tomcat默認使用的是DBCP數據庫鏈接池,其實從本質上講,Tomcat是利用Apache Commons DBCP來實現的,只不過把特定的功能集成到了tomcat-dbcp.jar包中,這個包在tomcat的lib裏面.

1.配置context.xml

    注意:(1)不是Context.xml,這個須要看你tomcat裏面conf目錄下是context.xml仍是Context.xml,和這個同樣就行.

        (2)這個配置便可以在${CATALINA_HOME}/conf/context.xml裏配置,(CATALINA_HOME是你tomcat的安裝目錄)

        也能夠在${CATALINA_HOME}/webapps/項目名/META-INF/context.xml裏,(項目名就是webapps下的一些目錄名稱,

        好比:ROOT.若是ROOT下沒有META-INF,那麼建立一個就行,而後再在META-INF裏建立文檔context.xml)

clipboard.png

如何將tomcat-dbcp數據源使用到項目中呢 有以下配置併發

在web項目的web.xml中加入資源引用:(可省略)
<resource-ref>
<description>JNDI DataSource</description>
<res-ref-name>jndi/testdb</res-ref-name>
<res-type>javax.sql.DataSource</res-type>
<res-auth>Container</res-auth>
</resource-ref>

啓動的時候加載tomcat配置的JNDI 公開數據源,其中res-ref-name值要和server.xml 、context.xml的name值一致。app

在web項目中配置spring數據源bean信息:

<bean id="dataSource"class="org.springframework.jndi.JndiObjectFactoryBean">
<propertyname="jndiName">
<value>java:comp/env/jndi/testdb</value>
 </property>
</bean>
直接替換項目WEB-INF/conf/data-access-config.xml文件中 beanid=」dataSource」 的節點便可使用

可是因爲考慮到使用jndi配置數據源對已有程序影響較大,因此最後只是升級了common-dbcp版原本獲取更高的性能。以上就是解決這個問題大體的過程。
參考:
https://blog.csdn.net/lzwglor...
http://elf8848.iteye.com/blog...
https://blog.csdn.net/Jacabe/...
https://blog.csdn.net/acoolpe...
https://blog.csdn.net/u011487...webapp

相關文章
相關標籤/搜索