天天看点

mysql出现大量未认证连接,MYSQL连接8小时未动出现连接异常解决方法

数据库连接出错信息有下面两条:

com.mysql.jdbc.exceptions.MySQLNonTransientConnectionException: No operations allowed after connection closed.Connection was implicitly closed due to underlying exception/error:

com.mysql.jdbc.CommunicationsException: Communications link failure

================分割线================

一直想不出什么原因导致,网上查资料也不顺利,后来找到了hibernate连接数据库,产生同样的错误时的处理方法,知道了问题出在哪里:

com.mysql.jdbc.CommunicationsException: Communications link failure due to underlying exception:

查看了Mysql的文档,以及Connector/J的文档以及在线说明发现,出现这种异常的原因是:Mysql服务器默认的“wait_timeout”是8小时,也就是说一个connection空闲超过8个小时,Mysql将自动断开该 connection。这就是问题的所在,在C3P0 pools中的connections如果空闲超过8小时,Mysql将其断开,而C3P0并不知道该connection已经失效,如果这时有 Client请求connection,C3P0将该失效的Connection提供给Client,将会造成上面的异常。

上网搜索,在MySQL的论坛上找到一个办法,就是如果在执行sql语句的时候发生了上述异常,就将sql语句重新执行一次。

试验发现,这个办法对这个使用spring+hibernate的服务无效。

进一步搜索发现,MySQL官方不推荐使用autoReconnect=true,参见http://bugs.mysql.com/bug.php?id=5020

需要另外找别的办法来解决这个问题。

由于问题产生的根本原因在于服务到数据库的连接长时间没活动,既然重新连接的办法无效,就可以尝试另外一种办法,就是反空闲。

自己写一个线程来反空闲的话,比较麻烦。

最后在网上找到一个办法。为hibernate配置连接池,推荐用c3p0,然后配置c3p0的反空闲设置idle_test_period,只要小于MySQL的wait timeout即可。

在hibernate.cfg.xml中增加下面几项:

org.hibernate.connection.C3P0ConnectionProvider

5

30

1800

50

1

120

true

修改完后测试,问题解决。

================分割线================

具体修改方法如下:

对于MySQL5之前的版本,如Mysql4.x,只需要修改连接池配置中的URL,添加一个参数:autoReconnect=true(如jdbc:mysql://hostaddress:3306/schemaname?autoReconnect=true),如果是MySQL5及以后的版本,则需要修改my.cnf(或者my.ini)文件,在[mysqld]后面添加上:

wait_timeout = n

interactive-timeout = n

(n为服务器关闭交互式连接前等待活动的秒数。可是就部署而言每次修改my.ini比较麻烦,而且n等于多少才是合适的呢?所以这个解决办法不好。)

查ibatis文档后修改如下,红字部分是修改的重点:

value="jdbc:mysql://192.168.1.4:3306/mail?characterEncoding=utf-8" />