我使用struts2+Hibernate开发了个j2ee小系统,数据库用的是mysql5,部署的服务器为weblogic10;
一般情况下没有什么问题,在开发中也是偶然发现,我的电脑没有关,部署的服务器一直运行着,长时间没有使用,第二天一来再点击系统,则后台出现如下异常:
** BEGIN NESTED EXCEPTION ** java.net.SocketException MESSAGE: Software caused connection abort: socket write error STACKTRACE: java.net.SocketException: Software caused connection abort: socket write error 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:2631) at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:1548) at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:1659) at com.mysql.jdbc.Connection.execSQL(Connection.java:3118) at com.mysql.jdbc.PreparedStatement.executeInternal(PreparedStatement.java:1143) at com.mysql.jdbc.PreparedStatement.executeQuery(PreparedStatement.java:1256) at org.hibernate.jdbc.AbstractBatcher.getResultSet(AbstractBatcher.java:208) at org.hibernate.loader.Loader.getResultSet(Loader.java:1808) ....... ** END NESTED EXCEPTION ** Last packet sent to the server was 0 ms ago.
在重启服务器后,一切又正常运行。
从以上异常可以看出,是weblogic服务器与mysql数据库服务器之间已失去连接。
原因是:MySQL wait timeout的值默认是28800 (3600*8),即一个连接在8小时内没有活动,就会自动断开该连接。
即使手动去设置wait timeout,最多只能是32767,不能再大了。
由于问题产生的根本原因在于服务到数据库的连接长时间没活动,那么接下来就是想法法来解决它:反空闲:
我使用的是c3po连接池, 配置c3p0的反空闲设置idle_test_period,只要小于MySQL的wait timeout即可.
hibernate.cfg.xml文件中加入的连接池的配置如下:
<!-- 为解决长时间不用连接异常,这是主要的 --> <property name="hibernate.connection.provider_class">org.hibernate.connection.C3P0ConnectionProvider</property> <!-- 最大连接数 --> <property name="hibernate.c3p0.max_size">30</property> <!-- 最小连接数 --> <property name="hibernate.c3p0.min_size">5</property> <!-- 获得连接的超时时间,如果超过这个时间,会抛出异常,单位毫秒 --> <property name="hibernate.c3p0.timeout">1800</property> <!-- 最大的PreparedStatement的数量 --> <property name="hibernate.c3p0.max_statements">50</property> <!-- 每隔120秒检查连接池里的空闲连接 ,单位是秒--> <property name="hibernate.c3p0.idle_test_period">120</property> <!-- 当连接池里面的连接用完的时候,C3P0一下获取的新的连接数 --> <property name="hibernate.c3p0.acquire_increment">2</property> <!-- 每次都验证连接是否可用 --> <property name="hibernate.c3p0.validate">true</property>