最全Druid异常整理,在开发过程中不断整理,持续更新。

1.  c.a.druid.pool.DruidDataSource - recyle error java.lang.InterruptedException: null

先来看看异常抛出代码DruidDataSource类

/** * 回收连接 */
protected void recycle(DruidPooledConnection pooledConnection) throws SQLException {} 

这个是Druid连接回收的方法,具体抛出代码为lock.lockInterruptibly();如下图

从代码中可以看出,是线程中断抛出异常,导致连接回收失败。这是一个偶发的场景,但每发生一次都会使一个数据库连接长时间被占用,长时间累计势必耗尽所有连接,造成严重的后果。

那触发的场景是什么呢?

一个场景是通过线程池并行执行任务,超时取消:

executorService.invokeAll(tasks, 300, TimeUnit.MILLISECONDS);

类似于这种代码,第二个参数300就是超时时间,如果超过时间Future任务还在执行就取消

来看一下取消的具体代码,FutureTask的方法

可见任务取消时设置了线程中断t.interrupt();

然后在DruidDataSource释放回收连接时是获取的可中断锁:this.lock.lockInterruptibly(); 所以导致抛出了异常。

该bug在Druid GitHub官网已经提出,在新版本中修复了,具体issue地址:

https://github.com/alibaba/druid/issues/785

解决方案:升级jar包版本,新版本已经解决。

<dependency>
   <groupId>com.alibaba</groupId>
   <artifactId>druid</artifactId>
   <version>1.1.12</version>
</dependency>