项目部署在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