項目部署在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)
如何將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