这两天在工作中遇到一个BUG.
项目里有一个定时计算任务,主要功能就是从原始数据表计算汇总一些数据然后更新到汇总表.这个定时任务是多线程同时进行计算更新的,因为要汇总的数据包括很多家企业的以天为单位的数据,单线程执行太耗费时间.
然而在计算任务跑完后控制台报错了如下错误:
java.sql.SQLException: Connection has already been closed.
这个错误从字面上看,直接原因就是程序试图向数据库发送指令或数据,然后发现这个数据库连接实际上已经关闭了,于是报了使用的数据库连接已经关闭的错误.
那么我的第一反应就是数据库的锅,因为在项目的数据库配置中有
edba.default.testOnBorrow=”true”
edba.default.validationQuery=”SELECT 1”
这两行配置,testOnBorrow参数为true之后,从连接池池中取出数据库连接前会使用validationQuery参数配置的检查语句,进行检验该连接是否还保持连接状态,如果检验失败,则从池中去除连接并尝试取出另一个.
也就是说这个参数为true已经保证了所有线程取得的数据库连接必然是正常的.
那么大概是数据库方面主动关闭了这个连接?
但是我又转念一想,数据库主动关闭连接应该也只会发生在闲置了一段时间没有发送过命令的连接上,而这个项目的每个连接都在一直发送命令啊,难道数据库会因为某个连接的连接时间过长而关闭连接?还是闲置连接参数被设的太短了,某个连接的sql执行时间太长,超过了闲置时间?
不管怎么样,还是先查一下数据库吧.我们项目用的是mysql的数据库.
于是使用show variables去查询相关的参数,并且查看各参数的含义.
**结果发现wait_timeout这个参数是默认的28800秒即8小时,并且该参数是等待超时时间,即连接闲置时间.
mysql也没有自动关闭长时间的连接的参数.**
看来是我错怪数据库了,但是这样的话,就有点陷入僵局了,既然数据库没有关闭过连接,连接池又保证给定时任务线程的连接是保持连接状态的.那么为什么会发生连接已经关闭的情况呢?只能回去再仔细看看日志了.
14:37:30.671 [main] INFO c.u.t.s.r.EnterpriseGroupAndRegionTask - electric stat report end! [2016-09-09 02:37:30]
14:37:30.673 [main] INFO c.u.t.s.r.EnterpriseGroupAndRegio