項目部署在tomcat后每隔一段時間便會報錯
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 的默認設置下,當一個連接的空閑時間超過8小時后,MySQL 就會斷開該連接,而 c3p0/dbcp 連接池則以為該被斷開的連接依然有效。在這種情況下,如果客戶端代碼向c3p0/dbcp 連接池請求連接的話,連接池就會把已經失效的連接返回給客戶端,客戶端在使用該失效連接的時候即拋出異常。
於是簡單的修改了mysql的設置
#my.cnf
wait_timeout=31536000
interactive_timeout=31536000
但是這樣改動的話wait_timeout太大了,會保留太多的無效鏈接,於是就從連接池上采取改動。在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秒,泄露的連接可以被刪除的超時值
配置后問題得到解決。
查看資料的過程中發現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-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值一致。
在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...