欢迎光临软文代写网站

代写软文平台

提供专业的软文代写公众号代运营方法

*** 次数:51505 已用完,请联系开发者*** [代写软文怎么接任务]定时任务和jdbc连接池的耗尽问题

作者:jcmp      发布时间:2021-04-25      浏览量:0
最近在一个项目中使用spring

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

问题的描述:

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

问题查找:

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

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

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

问题解决:

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

总结:

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