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

相关文章
相关标签/搜索