数据源一开始配置:

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. call_user_func()的参数不能为引用传递 自定义替代方法

    php手册 中关于 请注意,传入call_user_func()的参数不能为引用传递. 关于这个情况的解释,可自己搜索.我们可以自己定义一个函数解决这样的问题,实例如下: <?php ini_s ...

  2. iOS:frame访问、设置简化

    看到一些程序都有这种写法,也不知道原创者是谁了.先在博客保存下. 在.m文件 #import "UIView+MyFrameCategory.h" @implementation ...

  3. SQL Server快速查询某张表的当前行数

    传统做法可能是select count(1) 但是往往会比较慢.推荐如下做法: ) CurrentRowCount FROM sys.sysindexes WHERE id = OBJECT_ID(' ...

  4. Highchart插件简介和引入方式

    一.Highchart简介: Highcharts 是一个用纯 JavaScript 编写的一个图表库, 能够很简单便捷的在 Web 网站或是 Web 应用程序添加有交互性的图表. Highchart ...

  5. 【Bootstrap-插件使用】Jcrop+fileinput组合实现头像上传功能

    作者:Dreawer链接:https://zhuanlan.zhihu.com/p/24465742来源:知乎著作权归作者所有.商业转载请联系作者获得授权,非商业转载请注明出处. 作者:梦游的龙猫(转 ...

  6. SQL优化技术分析-1:操作符优化

    1.IN 操作符 用IN写出来的SQL的优点是比较容易写及清晰易懂,这比较适合现代软件开发的风格.但是用IN的SQL 性能总是比较低的,从Oracle执行的步骤来分析用IN的SQL与不用IN的SQL有 ...

  7. redis数据结构存储Linked List设计细节(redis的设计与实现笔记)

    redis里拥有一个灵活扩展且获取表头表尾复杂度为O(1)的双端列表,分为list和listNode2部分组成. list: typedef struct list {//链表 listNode *h ...

  8. xml节点查询

    关键词: XName XElement Descendance() node.Name.LocalName 示范: List<ClaimSheetBaseDto> list = new L ...

  9. Windows 10下使用U盘安装Ubuntu双系统

    问题描述:在Windows10下安装Ubuntu. 使用工具:Windows10.Ubuntu16.04 LTS安装包.UltraISO.easyBCD. 操作步骤: 1.安装之前要给Ubuntu分出 ...

  10. 用 JSP 实现对文件的相关操作

    前段时间一直忙着作业,实验,动手的时间真是少之又少,今天终于可以继续和大家分享关于 JSP 的学习心得. 简单总结一下吧: JSP 理论性很强,感觉就是纯语法. 我更偏向于实际编写代码,这样更容易理解 ...