数据源一开始配置:

jdbc.initialSize=1
jdbc.minIdle=1
jdbc.maxActive=5

程序运行一段时间后,执行查询抛如下异常:

exception=org.mybatis.spring.MyBatisSystemException: nested exception is org.apache.ibatis.exceptions.PersistenceException:
### Error querying database. Cause: org.springframework.jdbc.CannotGetJdbcConnectionException: Could not get JDBC Connection; nested exception is com.alibaba.druid.pool.GetConnectionTimeoutException: wait millis 60000, active 5, maxActive 5
### The error may exist in ...

怀疑是最大连接数不够,讲配置改为

jdbc.initialSize=1
jdbc.minIdle=1
jdbc.maxActive=20

运行一段时间后,又出现上述异常。在datasource配置中添加如下参数(参考http://www.cnblogs.com/netcorner/p/4380949.html):

<!-- 超过时间限制是否回收 -->
<property name="removeAbandoned" value="true" />
<!-- 超时时间;单位为秒。180秒=3分钟 -->
<property name="removeAbandonedTimeout" value="180" />
<!-- 关闭abanded连接时输出错误日志 -->
<property name="logAbandoned" value="true" />

抛如下异常:

2016-12-27 14:35:22.773 [Druid-ConnectionPool-Destroy-1821010113] ERROR com.alibaba.druid.pool.DruidDataSource - abandon connection, owner thread: quartzScheduler_Worker-1, connected time nano: 506518587214834, open stackTrace
at java.lang.Thread.getStackTrace(Thread.java:1552)
at com.alibaba.druid.pool.DruidDataSource.getConnectionDirect(DruidDataSource.java:1014)
at com.alibaba.druid.filter.FilterChainImpl.dataSource_connect(FilterChainImpl.java:4544)
at com.alibaba.druid.filter.stat.StatFilter.dataSource_getConnection(StatFilter.java:662)
at com.alibaba.druid.filter.FilterChainImpl.dataSource_connect(FilterChainImpl.java:4540)
at com.alibaba.druid.pool.DruidDataSource.getConnection(DruidDataSource.java:938)
at com.alibaba.druid.pool.DruidDataSource.getConnection(DruidDataSource.java:930)
at com.alibaba.druid.pool.DruidDataSource.getConnection(DruidDataSource.java:102)
at com.xxx.doCopyIn(AppQustionSync.java:168)
at com.xxx.executeInternal(AppQustionSync.java:99)
at org.springframework.scheduling.quartz.QuartzJobBean.execute(QuartzJobBean.java:75)
at org.quartz.core.JobRunShell.run(JobRunShell.java:202)
at org.quartz.simpl.SimpleThreadPool$WorkerThread.run(SimpleThreadPool.java:573)

红色标注处连接未释放,查看代码,

    try {
InputStream input = new FileInputStream(dataFile);
conn = copyInDataSource.getConnection();
baseConn = (BaseConnection) conn.getMetaData()
.getConnection();
baseConn.setAutoCommit(false);
stmt = baseConn.createStatement();
LOG.info("delete data: " + delSql);
stmt.executeUpdate(delSql);
CopyManager copyManager = new CopyManager(baseConn);
LOG.info("copy in: " + copyInSql);
copyManager.copyIn(copyInSql, input);
baseConn.commit();
jobDataMap.remove(data_file_path_key);
} catch (SQLException e) {
try {
LOG.warn(JobDataMapHelper.jobName(jobDataMap) + ":"
+ "批量更新任务失败回滚...");
baseConn.rollback();
} catch (SQLException ex) {
String errorMessage = String.format(
"JobName:[%s] failed: ",
JobDataMapHelper.jobName(jobDataMap));
throw new SQLException(errorMessage, ex);
}
} finally {
stmt.close();
baseConn.close();
jobDataMap.remove(data_file_path_key);
FileUtils.deleteQuietly(dataFile);
}

这里baseConn是通过druid datasource获取的一个PgSQL 底层连接, 上面代码执行完后,finally中调用baseConn.close()关闭了这个连接,(猜测关闭这个底层连接,druid连接池却不知道,还认为自己拥有这个连接,但实际该连接是不可用的,这段代码执行多次,就将druid连接池中所有连接都耗光了,于是便抛出Could not get JDBC Connection错误。

将上面finally代码块改为

finally {
stmt.close();
conn.close();
jobDataMap.remove(data_file_path_key);
FileUtils.deleteQuietly(dataFile);
}

即只调用druid 连接的close方法(只是释放该连接,而不是直接关闭底层连接),问题解决。

druid连接池获取不到连接的一种情况的更多相关文章

  1. JDBC实例--JDBC连接池技术解密,连接池对我们不再陌生

    一.为什么我们要用连接池技术? 前面的数据库连接的建立及关闭资源的方法有些缺陷.统舱传统数据库访问方式:一次数据库访问对应一个物理连接,每次操作数据库都要打开.关闭该物理连接, 系统性能严重受损. 解 ...

  2. 线程池-连接池-JDBC实例-JDBC连接池技术

    线程池和连接池   线程池的原理:     来看一下线程池究竟是怎么一回事?其实线程池的原理很简单,类似于操作系统中的缓冲区的概念,它的流程如下:先启动若干数量的线程,并让这些线程都处于睡眠状态,当客 ...

  3. dbcp2连接池获取数据库连接Connection

    一.先来看看手工创建的方式 public static Connection getConnection() { Connection conn = null; try { Class.forName ...

  4. JSP(Servlet)中从连接池获取连接

    1) 建立连接. 2) 执行SQL. 3) 处理结果. 4) 释放资源. Connection pool:连接池 DataSource: LDAP ( Light directory access p ...

  5. JavaWeb之数据源连接池(4)---自定义数据源连接池

    [续上文<JavaWeb之数据源连接池(3)---Tomcat>] 我们已经 了解了DBCP,C3P0,以及Tomcat内置的数据源连接池,那么,这些数据源连接池是如何实现的呢?为了究其原 ...

  6. JDBC数据源连接池(4)---自定义数据源连接池

    [续上文<JDBC数据源连接池(3)---Tomcat集成DBCP>] 我们已经 了解了DBCP,C3P0,以及Tomcat内置的数据源连接池,那么,这些数据源连接池是如何实现的呢?为了究 ...

  7. Druid数据库连接池获取连接阻塞(转载)

    一. 背景        17年公司有个项目组在南京做项目的时候,开发框架用的是spring boot ,数据库连接池用的是druid,但老是遇到socket read timeout的错误,不得已放 ...

  8. java 代码实现使用Druid 链接池获取数据库链接

    因为原先使用的c3p0链接池,时常出现:APPARENT DEADLOCK!!! Creating emergency threads for unassigned pending tasks,以及出 ...

  9. JDBC数据源 使用JNDI连接池实现数据库的连接

    0.引言 许多Web应用程序需要通过JDBC驱动程序访问数据库,以支持该应用程序所需的功能.Java EE平台规范要求Java EE应用程序服务器为此目的提供一个DataSource实现(即,用于JD ...

随机推荐

  1. Javascript高性能编程-提高数据访问速度

         hasOwnProperty()仅检索实例不检索原型,in即检索实例,又检索原型      成员嵌套越深,访问速度越慢,只在必要的情况下使用对象成员.      如果在同一个函数中你要多次读 ...

  2. plist文件、NSUserDefault 对文件进行存储的类、json格式解析

    ========================== 文件操作 ========================== Δ一 .plist文件 .plist文件是一个属性字典数组的一个文件: .plis ...

  3. iOS 切换首页-更改tabbar的容器控制器

    最近想到的一个小需求: 首页切换:点击一个切换按钮,能实现首页的风格.排版等变换,原理是用一个新的VC替换掉. 效果如下:   ====>====> 实现方式很简单: 以我的Demo为例, ...

  4. 使Python IDLE也变得高颜值

    初学Python,大家应该都是用Python自带的IDLE了,我们可以让他颜值高一些,这样敲出的代码就赏心悦目,比如像下面这样:   我们首先要找到名为config-highlight.cfg的文件, ...

  5. android onNewIntent调用时机

    (转自:http://www.cnblogs.com/zenfly/archive/2012/02/10/2345196.html) 在IntentActivity中重写下列方法:onCreate o ...

  6. [转]Asp.Net Core 简单的使用加密的Cookie保存用户状态

    本文转自:http://www.cnblogs.com/Joes/p/6023820.html 在以前的Asp.Net中可以用 FormsAuthentication 类的一系列方法来使用加密的Coo ...

  7. 连接有密码的mongodb

    mongoose: db.openSet("mongodb://admin:pass@192.168.1.100:27017/mydb");

  8. 使用FastReport打印二维码

    简单介绍一下该功能所在的项目背景:C#语言编写的WPF客户端应用程序,在“结账”模块中,打印出的收款小票上需要显示一个二维码,服务生拿着小票去找顾客,顾客可以选择现金.银行卡等普通支付方式,也可以直接 ...

  9. Hibernate 缓存机制浅析

    1. 为什么要用 Hibernate 缓存? Hibernate是一个持久层框架,经常访问物理数据库. 为了降低应用程序对物理数据源访问的频次,从而提高应用程序的运行性能. 缓存内的数据是对物理数据源 ...

  10. 「坐上时光机,查找编译压缩后的文件最初的样子」gulp-sourcemaps 使用说明

    一般我们调试的 js/css 文件都是编译压缩后的,一旦出错很难定位原始的位置,gulp-sourcemaps 的出现帮助我们解决了这个问题. 首先我们看下目录结构: css js a.js b.js ...