MySql数据库如果超过8小时处于空闲状态,则会自动断开连接,报连接超时错误,错误代码如下:
java.net.SocketException MESSAGE: Broken pipe STACKTRACE: java.net.SocketException: Broken pipe at java.net.SocketOutputStream.socketWrite0(Native Method) at java.net.SocketOutputStream.socketWrite(SocketOutputStream.java:92) at java.net.SocketOutputStream.write(SocketOutputStream.java:136) at java.io.BufferedOutputStream.flushBuffer(BufferedOutputStream.java:65) at java.io.BufferedOutputStream.flush(BufferedOutputStream.java:123) at com.mysql.jdbc.MysqlIO.send(MysqlIO.java:2637) at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:1554) at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:1665) at com.mysql.jdbc.Connection.execSQL(Connection.java:3176) at com.mysql.jdbc.PreparedStatement.executeInternal(PreparedStatement.java:1153) at com.mysql.jdbc.PreparedStatement.executeQuery(PreparedStatement.java:1266)
如果使用hibernate自带的连接池则极易出现此问题,上网翻阅了大量的资料,现总结出解决此问题的几种方法:
(1)修改mysql的my.ini文件,增加如下配置:
[mysqld]
# The TCP/IP Port the MySQL Server will listen on
port=3306
# added from now
socket = /tmp/mysql.sock
# 单位是秒,相当于24小时,原来默认为28800即8小时
wait_timeout=86400
interactive_timeout = 86400
# added end
(2)改用proxool连接池方法:
配置proxool.xml文件内容如下:
<?xml version="1.0" encoding="UTF-8"?> <something-else-entirely> <proxool> <!--连接池的别名--> <alias>testDB</alias> <!--proxool只能管理由自己产生的连接--> <driver-url> jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=GBK&autoReconnect=true&zeroDateTimeBehavior=convertToNull </driver-url> <!--JDBC驱动程序--> <driver-class>com.mysql.jdbc.Driver</driver-class> <driver-properties> <property name="user" value="root" /> <property name="password" value="root" /> </driver-properties> <!-- proxool自动侦察各个连接状态的时间间隔(毫秒),侦察到空闲的连接就马上回收,超时的销毁--> <house-keeping-sleep-time>900000</house-keeping-sleep-time> <house-keeping-test-sql> select CURRENT_DATE </house-keeping-test-sql> <!-- 指因未有空闲连接可以分配而在队列中等候的最大请求数,超过这个请求数的 用户连接就不会被接受--> <maximum-new-connections>20</maximum-new-connections> <!-- 最少保持的空闲连接数--> <prototype-count>5</prototype-count> <!-- 允许最大连接数,超过了这个连接,再有请求时,就排在队列中等候,最大的 等待请求数由maximum-new-connections决定--> <maximum-connection-count>100</maximum-connection-count> <!-- 最小连接数--> <minimum-connection-count>10</minimum-connection-count> </proxool> </something-else-entirely>
配置hibernate.cfg.xml文件内容如下:
<!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd"> <hibernate-configuration> <session-factory> <property name="hibernate.connection.provider_class"> org.hibernate.connection.ProxoolConnectionProvider </property> <property name="hibernate.proxool.pool_alias">testDB</property> <property name="hibernate.proxool.xml">proxool.xml</property> <property name="dialect"> org.hibernate.dialect.MySQLDialect </property> <property name="show_sql">true</property> <mapping resource="tt/TT.hbm.xml" /> </session-factory> </hibernate-configuration>
java类中的调用方式如下:
Class.forName("org.hibernate.connection.ProxoolConnectionProvider"); Connection con = DriverManager.getConnection("proxool.testDB");
用完连接后,记得释放就可以了。
当然还有其它连接池的配置方式,方法大致相同,就不在此一一列举。