最全Druid异常整理,在开发过程中不断整理,持续更新。
先来看看异常抛出代码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>