Can’t connect to MySQL server on ‘localhost’(10055) + Can not open connection + Could not execute query

来源:互联网 发布:手机网络限速怎么解除 编辑:程序博客网 时间:2024/06/05 19:19

本菜鸟还是学生,用Hibernate和MySQL开发项目,仅停留在使用阶段,对MySQL和Hibernate没有深入研究。

刚做完一个Web项目,数据库用MySQL,用Hibernate进行数据库的操作,挂到服务器上后出现如下问题:

1  如果长时间没访问,访问好后会出现could not open connection的错误,而且mysql也无法登陆,登陆mysql时提示:Can't

connect to MySQL server on 'localhost' (10055) ,重启mysql服务和Tomcat均不起作用,重启服务器后恢复正常,但过段时间后

又会重新异常。

    解决方案: 修改注册表中册:TcpTimedWaitDelay这个键的值,原理不详。

    方法:使用 regedit 命令访问 HKEY_LOCAL_MACHINE/SYSTEM/CurrentControlSet/ Services/TCPIP/Parameters 注册表子键并

创建名为 TcpTimedWaitDelay 的新 REG_DWORD 值。 将此值设置为十进制 30,其为十六进制 0×0000001e。该值将等待时间设置为

30 秒。


2 在改完以上问题后,过了一阵子,错误变成了另外一个:could not execute query。重启Tomcat后恢复正常。
 原因:MySQL会关闭一个8小时都不活动的链接。可以show variables查看mysql的wait_time这个参数的值为28800即8小时。
因此如果web应用程序8小时没有访问,则MySQL会单方面的关闭同Hibernate的连接,而此时如果有用户访问,则会将已经断开的连接

返回给用户,导致could not execute query;

 
   这可以说到Hibernate所是用的数据库连接池的问题。据说Hibernate3.0以后的版本已经将默认连接池改成了c3p0,不过文档中是

这么写的:Hibernate默认使用的数据库连接池是Apache的DBCP,c3p0的jar包也随着Hibernate的包发布了,如果在

hibernate.cfg.xml中配置了c3p0的属性的话,则会使用c3p0这个连接池(hibernate_reference.pdf 的3.3节有关于这些的描述),

而这些属性中就包括了连接的最大空闲时间的设置。

 解决的方法有3种:

        增加wait_timeout的时间(设置MySQL的参数,未研究)。
        减少Connection pools中connection的lifetime(小于28800,让C3P0先于MySQL断开连接即可)。
        测试Connection pools中connection的有效性(未研究)
 
 第一种配置如下:
 为了安全起见这里还是设置了hibernate.connection.provider_class这个属性,直接指定c3p0作为连接池。
 
 配置如下:
 <property name="connection.provider_class">org.hibernate.connection.C3P0ConnectionProvider</property>
 
 <property name="c3p0.timeout">10000</property>

 因为10000小于28800,如果空闲超过了10000,当再有数据库连接的请求来的时候,由于C3P0已经将该连接作废,因此会重

新建立连接,同理当大于28800的时候,MySQL已经断开了连接,C3P0也已经将该连接断开,于是会重新建立连接,不存在将错误的连

接返回的情况。