• tomcat7使用dbcp连接池遇到的坑


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

    原文地址:https://segmentfault.com/a/1190000017065607

  • 相关阅读:
    申请Google Adsense通过终审的关键点
    Google Adsense(谷歌网站联盟)广告申请指南
    年轻人请不要轻易在公司离职!(转)
    自己定义开发线程池
    js 闭包,作用域,this 终结篇(转)
    javaweb 发布目录
    linux中SCP的用法
    win10系统win10搜索框不能用 解决方案
    【经验总结】linux 安装python (替换系统自带的python版本)
    大数据Hadoop生态体系,环境搭建到集群管理
  • 原文地址:https://www.cnblogs.com/lalalagq/p/9985834.html
Copyright © 2020-2023  润新知