No operations allowed after connection closed.错误

今天客户现场那边出现了一个诡异的问题,前台的错误提示为:

Caused by: org.hibernate.TransactionException: rollback failed

想着不会啊,这样的问题都能搞出来,真是牛啊.

于是拖下了日子,原来是程序与数据库断开连接了。

Caused by: com.mysql.jdbc.exceptions.jdbc4.MySQLNonTransientConnectionException: No operations allowed after connection closed.
at sun.reflect.GeneratedConstructorAccessor560.newInstance(Unknown Source)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27)
at java.lang.reflect.Constructor.newInstance(Constructor.java:513)
at com.mysql.jdbc.Util.handleNewInstance(Util.java:411)
at com.mysql.jdbc.Util.getInstance(Util.java:386)
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:1013)
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:987)
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:982)
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:927)
at com.mysql.jdbc.ConnectionImpl.throwConnectionClosedException(ConnectionImpl.java:1205)
at com.mysql.jdbc.ConnectionImpl.checkClosed(ConnectionImpl.java:1197)
at com.mysql.jdbc.ConnectionImpl.setAutoCommit(ConnectionImpl.java:4954)
at org.jboss.resource.adapter.jdbc.BaseWrapperManagedConnection.checkTransaction(BaseWrapperManagedConnection.java:547)
at org.jboss.resource.adapter.jdbc.WrappedConnection.checkTransaction(WrappedConnection.java:836)
at org.jboss.resource.adapter.jdbc.WrappedConnection.prepareStatement(WrappedConnection.java:250)
at sun.reflect.GeneratedMethodAccessor379.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.hibernate.engine.jdbc.internal.proxy.ConnectionProxyHandler.continueInvocation(ConnectionProxyHandler.java:138)
… 123 more
Caused by: com.mysql.jdbc.exceptions.jdbc4.CommunicationsException: Communications link failure

分析,出现这种异常的原因是:
Mysql服务器默认的“wait_timeout”是8小时,也就是说一个connection空闲超过8个小时,Mysql将自动断开该connection。这就是问题的所在,在C3P0 pools中的connections如果空闲超过8小时,mysql将其断开,而C3P0并不知道该connection已经失效,如果这时有Client请求connection,C3P0将该失效的Connection提供给Client,将会造成上面的异常。
a)解决的方法有3种:
    增加wait_timeout的时间。
    减少Connection pools中connection的lifetime。
    测试Connection pools中connection的有效性。
b)具体解决方案:
1、换一下JDBC驱动,JDBC3.1.0-alpha及以前版本会出现此问题,下载新的JDBC驱动
  2、使用hibernate配置:
使用hibernate:
<property name=”connection.autoReconnect”>true</property>  <!–这个是最主要的–>
<property name=”connection.autoReconnectForPools”>true</property>
<property name=”connection.is-connection-validation-required”>true</property>
加入以上property,可解决此问题,如果未使用hibernate等持久化管理框架,可在mysql的url中加入autoReconnect=true,这样就可以解决。
原因很简单。在对数据库操作结束后关闭连接是正确的做法,没什么大问题。至于出现:No operations allowed after connection closed。这样的问题原因只有一个,你这里和数据库的连接Connection是一个Static的,程序共享这一个Connection。所以第一次对数据库操作没问题,当把Connection关闭后,第二次还想操作数据库时Connection肯定不存在了。

2 responses

  1. 我出的错估计和你说的差不多,但是我在hibernate.cfg.xml文件中配置了以下三个:
    true  
    true
    true
    还是没有解决,还是报了同样的错误,求解决。

发表评论

电子邮件地址不会被公开。 必填项已用*标注