zoukankan      html  css  js  c++  java
  • sql异常:nested exception is org.apache.commons.dbcp.SQLNestedException: Cannot get a connection, pool error Timeout waiting for idle object

    连接池满了:

    转自: http://chivas2008.blogbus.com/logs/28735149.html

    http://blog.csdn.net/foamflower/article/details/5369199

    解决的办法有3个

    1重启你的服务器

    2在content.xml中,将maxActive设置为零,或者调高它的值

    3在你的程序中正确关闭connections 这里有一点要注意要把关闭的语句写在finally中,如果你写在try{}中出现异常的话是无法正确关闭的。

    要象这样

    } catch (SQLException e) { 
    /** Exception handling **/ 
    } finally { 
    try { 
    if (stmt != null) 
    stmt.close(); 
    if (dbConnection != null) 
    dbConnection.close(); 
    } catch (SQLException e) { 
    /** Exception handling **/ 


    当然这3个方法里前两个并不能从根本上解决你的问题,所以还是要好好研究你的程序,一定要将用完的connection放回到池中。

    1 问题描述
    Web程序在tomcat刚开始运行时速度很快,但过一段时间后发现速度变得很慢。
    检查日志输出,发现异常如下:
    org.apache.commons.dbcp.SQLNestedException: Cannot get a connection, pool exhausted, cause: 
    java.util.NoSuchElementException: Timeout waiting for idle object
    同时在SQLServer事件探查器中发现,每执行一次sql语句都要产生Audit login事件,语句执行后产生
    Audit logout事件。说明每一次tomcat都是重新打开新的连接。
    2 问题解决
    tomcat 的数据源定义提供了三个参数:
    a. 如果设为true则tomcat自动检查恢复重新利用,没有正常关闭的Connection.(默认是false)
    <parameter>
    <name>removeAbandoned</name>
    <value>true</value>
    </parameter>
    b. 设定连接在多少秒内被认为是放弃的连接,即可进行恢复利用。
    <parameter>
    <name>removeAbandonedTimeout</name>
    <value>60</value>
    </parameter>
    c. 输出回收的日志,可以详细打印出异常从而发现是在那里发生了泄漏
    <parameter>
    <name>logAbandoned</name>
    <value>true</value>
    </parameter>
    B、Timeout waiting for idle object

    转自:http://203.208.37.132/search?q=cache:9TmBcAJrYhQJ:jiangzi87.blog.ccidnet.com/blog.php%3Fdo%3Dshowone%26itemid%3D474468%26typ%3Dblog+java.util.NoSuchElementException:+Timeout+waiting+for+idle+object&cd=5&hl=zh-CN&ct=clnk&gl=cn&st_usg=ALhdy2-dZRxeN0j7d6MJ0Shp7tXcjwyumQ

    1、request   too large错误 

      在我们应用系统中,有些用户反映在填写申请表的时候,有时会出现request too large 的错误,导致操作失败.经查看原因是: 用户在填写申请表的时候.我们会搁一定的时间,朝cookies里保存数据.如果cookies里数据过大,就会导致request too large 的错误,清除cookies,问题就可以解决.. 
    2、Timeout waiting for idle object错误
        org.apache.commons.dbcp.SQLNestedException: Cannot get a connection, pool exhausted, cause: 
        java.util.NoSuchElementExceptionTimeout waiting for idle object
    是因为连接没有关闭,导致其他的连接去连接这个老的连接。导致出错
    检查是否没有关闭数据库连接

        看到我对于A中红色显示的部分,这个参数对于查找原因真的很重要。初看上面的报错真得让我一头雾水,后来配置上这个参数,再运行控制台的报错信息更加明确,从报错信息中我找到了运行该功能存在两个地方连接池泄漏问题:

    at com.xxx.action.DoccatalogAction.getDocCatalogListByCatCode(DoccatalogAction.java:1178)


    at com.xxx.organization.dao.hibernate.UserHibernateDAOBean.getUserByName(UserHibernateDAOBean.java:54)
     at com.xxx.doc.desktopapp.action.DesktopAppAction.removeAllDataByCategoryList(DesktopAppAction.java:564)

    从中可以知道是在哪个方法,哪一行的代码存在连接池泄漏问题。

     【原因】:

             原来真的是同事写的代码中未对session,Connection,Statement等与数据库相关的连接未释放。

    【解决方法】:

            1、对于session的部分全部加上

                //避免未释放连接导致连接池耗尽
              Session session =  this.getSession();
              try{
                       //执行代码   ...
             }finally{
                this.releaseSession(session);
             }

           2、对于数据库连接

       Session session = listHelper.getSessionFactory().openSession();
       Connection cnn = null;
       Statement state = null;
       ResultSet rs = null;
       try{
          cnn = session.connection();
          state = cnn.createStatement(
          ResultSet.TYPE_SCROLL_INSENSITIVE,
          ResultSet.CONCUR_READ_ONLY);
          String strSQL="";
          strSQL+=" select d.* from tb_datapriv_grant  g , tb_datapriv  d where g.member_id='"+userid+"' ";
          
          rs = state.executeQuery(strSQL);//查询目录用户是否有权限
                     ......
        }finally{

        //关闭rs
        if(null!=rs){
         rs.close();
         rs = null;
        }
        //关闭state
        if(null!=state){
         state.close();
         state = null;
        }
        //关闭cnn
        if(null!=cnn){
         cnn.close();
         cnn = null;
        }
        //关闭session
        if(null!=session){
         session.close();
         session = null;
        }
       }

    当然,可能你的项目里获取session和释放session的方法和我的并不一样,因为有的类方法是我们封装好的。但是相同的是一定要记得释放。

  • 相关阅读:
    第五章 Python——字符编码与文件处理
    第六章 Python——函数与面向过程编程
    第七章 Python——模块与包
    第一章 计算机硬件基础与操作系统介绍
    luogu P1706 全排列问题
    luogu 2142 高精度减法
    luogu P1601 高精度加法
    luogu P1803 线段覆盖 贪心
    luogu P1031 均分纸牌 贪心
    luogu P2678 跳石头 二分答案
  • 原文地址:https://www.cnblogs.com/xiaodoujiaohome/p/4867556.html
Copyright © 2011-2022 走看看