资讯专栏INFORMATION COLUMN

tomcat7使用dbcp连接池遇到的坑

silenceboy / 2188人阅读

摘要:查看资料的过程中发现连接池是有两种的连接池与连接池。在分配对象或对象返回的时候,会锁定全部连接池。连接池使用接口获取底层连接连接池可以防止饥饿。当连接返回时,池就将唤醒正确的等待线程。

项目部署在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中加入资源引用:(可省略)

JNDI DataSource
jndi/testdb
javax.sql.DataSource
Container

启动的时候加载tomcat配置的JNDI 公开数据源,其中res-ref-name值要和server.xml 、context.xml的name值一致。

在web项目中配置spring数据源bean信息:



java:comp/env/jndi/testdb
 

直接替换项目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...

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/72258.html

相关文章

  • JAVA数据库连接总结

    摘要:目前主流的数据库连接池有等几种。默认值初始化连接池中的连接数,取值应在与之间,默认为最大空闲时间秒内未使用则连接被丢弃。当连接池中的连接耗尽的时候一次同时获取的连接数。每秒检查所有连接池中的空闲连接。 一、数据库连接池 数据库连接池的基本思想就是为数据库连接建立一个缓冲池,预先在缓冲池中放入一定数量的连接,当需要建立数据库连接时,只需要从缓冲池中取出一个,使用完之后在放回去,节省连接建...

    xioqua 评论0 收藏0
  • JDBC常见面试题

    摘要:常见面试题操作数据库的步骤操作数据库的步骤注册数据库驱动。可以防止注入,安全性高于。只有隔离级别才能防止产生幻读。对象维护了一个游标,指向当前的数据行。一共有三种对象。 以下我是归纳的JDBC知识点图: showImg(https://segmentfault.com/img/remote/1460000013312769); 图上的知识点都可以在我其他的文章内找到相应内容。 JDBC...

    Yuqi 评论0 收藏0
  • Tomcat 7 类加载器是如何实现的

    摘要:请注意,应用程序类加载器的模型与此略有不同,如下所述,但主要原则是相同的。此类由加载器搜索的位置中的属性定义。该服务器类加载器是唯一到内部可见,并且是应用程序完全不可见。 Tomcat 7 类加载器是如何实现的 概述 与许多服务器应用程序一样,Tomcat安装了各种类加载器(即实现的类java.lang.ClassLoader),以允许容器的不同部分和容器上运行的Web应用程序访问可用...

    trigkit4 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<