搜鞥都哦 发表于 2018-11-23 06:53:08

org.apache.commons.dbcp.SQLNestedException: Cannot get a connection, pool ex

  今天同事在测试文件同步功能时,发现当删除一个文件夹目录,里面含有很多文档的时候就报:
  Caused by: org.apache.commons.dbcp.SQLNestedException: Cannot get a connection, pool exhausted
  at org.apache.commons.dbcp.PoolingDataSource.getConnection(PoolingDataSource.java:103)
  at org.apache.commons.dbcp.BasicDataSource.getConnection(BasicDataSource.java:540)
  at org.springframework.orm.hibernate3.LocalDataSourceConnectionProvider.getConnection(LocalDataSourceConnectionProvider.java:81)
  at org.hibernate.jdbc.ConnectionManager.openConnection(ConnectionManager.java:423)
  ... 154 more

  Caused by: java.util.NoSuchElementException: Timeout waiting for>  at org.apache.commons.pool.impl.GenericObjectPool.borrowObject(GenericObjectPool.java:756)
  at org.apache.commons.dbcp.AbandonedObjectPool.borrowObject(AbandonedObjectPool.java:74)
  at org.apache.commons.dbcp.PoolingDataSource.getConnection(PoolingDataSource.java:95)
  ... 157 more
  2010-3-11 9:34:40 org.apache.catalina.core.ApplicationContext log
  信息: org.springframework.jdbc.CannotGetJdbcConnectionException: Could not get JDBC Connection; nested exception is org.apache.commons.dbcp.SQLNestedException: Cannot get a connection, pool exhausted
   ERROR 2010-03-11 09:34:41,859 JDBCExceptionReporter.logExceptions(78) | Cannot get a connection, pool exhausted
   ERROR 2010-03-11 09:34:41,859 JDBCExceptionReporter.logExceptions(78) | Cannot get a connection, pool exhausted
  org.hibernate.exception.GenericJDBCException: Cannot open connection
  ......
  初看org.apache.commons.dbcp.SQLNestedException: Cannot get a connection, pool exhausted知道是连接池已经耗尽了。
  心想不会是在删除的过程中,定时器已经启动了建索引进程,由于未控制线程数而导致连接池耗尽?
  但是看到同事的测试目录下文件数也不是很多,全部是图片,大概也有三四十张。但是建索引也不至于,平时会索引整个数据库文档表建索引那时的数量比这里大多了。
  网上一查:
  A、Cannot get a connection, pool exhausted解决办法
  转自:http://chivas2008.blogbus.com/logs/28735149.html
  解决的办法有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>  同时在SQLServer事件探查器中发现,每执行一次sql语句都要产生Audit login事件,语句执行后产生
  Audit logout事件。说明每一次tomcat都是重新打开新的连接。
  2 问题解决
  tomcat 的数据源定义提供了三个参数:
  a. 如果设为true则tomcat自动检查恢复重新利用,没有正常关闭的Connection.(默认是false)
  
  removeAbandoned
  true
  
  b. 设定连接在多少秒内被认为是放弃的连接,即可进行恢复利用。
  
  removeAbandonedTimeout
  60
  
  c.输出回收的日志,可以详细打印出异常从而发现是在那里发生了泄漏
  
  logAbandoned
  true
  
  B、Timeoutwaitingforidleobject
转自: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、Timeoutwaitingforidleobject错误
  org.apache.commons.dbcp.SQLNestedException: Cannot get a connection, pool exhausted, cause:
  java.util.NoSuchElementException:Timeoutwaitingforidleobject
  是因为连接没有关闭,导致其他的连接去连接这个老的连接。导致出错
  检查是否没有关闭数据库连接
  看到我对于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的方法和我的并不一样,因为有的类方法是我们封装好的。但是相同的是一定要记得释放。

页: [1]
查看完整版本: org.apache.commons.dbcp.SQLNestedException: Cannot get a connection, pool ex