![](https://img.haomeiwen.com/i3996991/b9391bfc6ef694da.png)
在有大规模任务执行期间,必然会出现报错,导致系统被大家误认为非常不稳定,因为量小的时候不会复现,而量大的时候复现,所以到底是谁close了这个connection?(大规模执行任务时,对该数据库的操作包括有增删改查)
第一反应怀疑sql语句问题,确实在insert的时候用了select last_insert_id(),遂去掉之,但是依然报错。
于是,又怀疑是数据库配置的问题
怀疑可能原因:
- socketTimeout,查询时间超过一定的阈值后,断开连接可以防止客户端的连接被一直占用。
- waitTimeout,服务器关闭非交互连接之前等待活动的秒数。
- 事务执行时间超时,连接被回收
- removeAbandonedTimeout参数,通过datasource.getConnontion() 取得的连接必须在removeAbandonedTimeout这么多秒内调用close(),不然就关闭连接
再看这几个可能的原因,前三种都被排除掉了,因为我这边除了上面图片报错,再没有其他报错了,如果是socketTimeOut或者waitTimeout应该会伴随其他Exception。而我们未使用任何数据库事务。
首先我换了一个数据库连接池,我们使用的是tomcat-jdbc,看了一篇文章,说tomcat-jdbc会把死链放回连接池,后来怎么也找不到这篇文章了,所以感觉这个观点可能是错误的。有大佬知道的,麻烦告知!!!
换了连接池换成了阿里的druid,然而依然报错,但是报错变了,变了之后就清晰起来了。
报错:connection holder is null
可能原因:removeAbandonedTimeout我们默认是5min,当一个连接在获取后5分钟还没释放,也就是获取到Connection后,未在5min中关闭连接,导致抛异常。
我的解决方案:调整了removeAbandonedTimeout=30分钟。
我现在还有一个疑问:我这只是一个insert语句,是什么原因使得他获取的数据库connection,5min还不释放呢?
这其实不是一个好的解决方案,应该通过业务上的优化或者修改sql语句等来避免此等问题的出现。此处我虽然记录了整个过程,然而并未更深入的了解,也并未找到更佳的解决方案。
借鉴文章=》
https://caotc.org/2016/09/12/java-debug-junit-connection-pool-config/
https://www.it610.com/article/3535095.htm
网友评论