定时任务和jdbc连接池的耗尽问题

最近在一个项目中使用spring的scheduling执行定时任务。简化一下需求,定时进行http请求,把请求的结果放入数据库,这里数据库连接使用c3p0连接池。

问题的描述:

执行了一段时间后,定时任务就停止了。日志输出停留在了某个时间点。查看java进程并没有挂掉。

问题查找:

通过最后的日志打印结束的位置是在获取数据库连接的地方停住了,原因应该就是无法获取连接。但为什么没有连接超时的异常。
看了一下c3p0的配置,发现spring中关于datasource的

<property name="checkoutTimeout" value="${c3p0.oa.checkoutTimeout}" /> 

这个配置注释了,这个配置就是获得连接的超时时间,如果超过这个时间,会抛出SQLException异常。如果没有这个超时配置,获取不到连接就会一直等待连接。
获取不到连接意味着c3p0连接池中的连接全部耗尽,定时任务执行完后,并没有把连接还给连接池,每次定时任务都从连接池获取新的连接,直至连接池达到最大连接数。

问题解决:

spring的scheduling使用线程池来执行定时任务的,线程是不会销毁的,线程从连接池获取连接后,执行任务,定时任务执行完成后,线程没有销毁,连接也就没有返回连接池。下次再次执行任务时,又从连接池中获取新的连接。这样最终把连接池的连接都耗尽了。
解决方法:
1.在任务执行完成后,主动关闭连接。而不是等待连接池回收连接。
2.开启一个新线程执行任务,新线程执行完毕后,线程会销毁,连接也会关闭。

总结:

使用线程池中的线程执行数据库操作时,如果是从连接池中获取连接的话,一定要关闭连接,否则会出现线程不销毁,连接就一直被占着,最终把连接池的连接耗光的情况。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 最原始的数据库连接就是我们打开一个连接,使用过后再关闭该链接来释放资源。频繁的新建打开再关闭连接对jvm和数据库都...
    野柳阅读 6,456评论 1 11
  • 第6章介绍了任务执行框架, 它不仅能简化任务与线程的生命周期管理, 而且还提供一 种简单灵活的方式将任务的提交与任...
    好好学习Sun阅读 1,206评论 0 2
  • layout: posttitle: 《Java并发编程的艺术》笔记categories: Javaexcerpt...
    xiaogmail阅读 5,878评论 1 19
  • 今天一大早就被一个新闻刷屏了,有一个人因为网络暴力自杀了。我觉得胸闷我不想说他的性别,他的工作,他居住的地方。在我...
    追逐_b1d3阅读 157评论 0 0
  • 超令跟9班的人打架了,被9班大炮给鼻子打出血了。超令有183公分长得很壮但9班大炮有190+长得更壮,那完全...
    幻想大贼阅读 278评论 0 1