首先表明:在网上找的
在说这个错误之前先说明我的项目是通过Hibernate来进行数据库操作的
关于MySQL连接超时问题,估计很多人都遇到过:大致情形都是这样,开发测试时程序都是正常的,一到第二天就出先莫名错误,比如在我的项目中就是定时任务执行,每天凌晨一点执行一次,也就是24小时每隔24小时执行,远远超出了8小时
如果你刚好在数据库超时的第一时间内看到日志记录的话那么,第一次超时发生的错误就是这样的:
ERROR [org.hibernate.util.JDBCExceptionReporter] - Communications link failure
Last packet sent to the server was 0 ms ago.
如果不是第一次超时后执行,以后每次报错就变成嵌套的错误了,就是下面这样:
ERROR [org.hibernate.util.JDBCExceptionReporter] -
No operations allowed after connection closed.Connection was implicitly closed due to underlying exception/error:
具体解释是这样的:Mysql服务器默认的“wait_timeout”是8小时【也就是默认的值默认是28800秒】,也就是说一个connection空闲超过8个小时,Mysql将自动断开该connection,通俗的讲就是一个连接在8小时内没有活动,就会自动断开该连接。
wait timeout的值可以设定,但最多只能是2147483,不能再大了。也就是约24.85天
所以即使你MySQL通过my.ini 在
# The TCP/IP Port the MySQL Server will listen on
port=3306下面添加
# this is myown dinifition for mysql connection timeout
wait_timeout=31536000
interactive_timeout=31536000
无论超过最大限度多大的数值,只能被MySQL解析为2147483,2147483天后你的程序该出什么错还是什么错,避免不了的
后来发现Hibernate的内置连接池性能是非常的差,还不如直接用第三方的c3p0,改用C3P0连接池,这
个连接池会自动 处理数据库连接被关闭的情况。要使用C3P0很简单,先从Hibernate里把c3p0-0.9.1.jar复
制到项目的lib目录中,再在 hibernate.properties里去掉hibernate.c3p0开头的那些属性的注释(使用缺
省值或自己需要的数值),这样 Hibernate就会自动使用C3P0代替内置的连接池了。到目前为止前面的问题
没有再出现过。
具体在hibernate.cfg.xml中配置如下(在<session-factory>下面一行配,参照官网)
<property name="hibernate.connection.provider_class">org.hibernate.connection.C3P0ConnectionProvider</property> <!--连接池的最小连接数--> <property name="hibernate.c3p0.min_size">5</property> <!--最大连接数--> <property name="hibernate.c3p0.max_size">30</property> <!--连接超时时间--> <property name="hibernate.c3p0.timeout">1800</property> <!--statemnets缓存大小--> <property name="hibernate.c3p0.max_statements">100</property> <!--每隔多少秒检测连接是否可正常使用 --> <property name="hibernate.c3p0.idle_test_period">121</property> <!--当池中的连接耗尽的时候,一次性增加的连接数量,默认为3--> <property name="hibernate.c3p0.acquire_increment">1</property> <property name="hibernate.c3p0.validate">true</property>