八进制

少年壮志无烟抽

  博客园 :: 首页 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::
  240 随笔 :: 0 文章 :: 3330 评论 :: 14 引用

在一个项目中,客户要求除操作系统外全部使用免费软件,因此我使用了Mysql 4.0作为数据库服务器,其JDBC驱动为3.0.9版本,在给客户安装后调试一切正常。可是到了第二天,只要一登录就提示“No operations allowed after connection closed”异常,显示在浏览器上。在经过一番检查后我发现,在这种情况下只要重新启动Tomcat就恢复正常,然而到了第二天问题依旧。

在网上查找一下,原来Mysql在经过8小时不使用后会自动关闭已打开的连接,摘录原文如下:

5.4.

I have a servlet/application that works fine for a day, and then stops working overnight

MySQL closes connections after 8 hours of inactivity. You either need to use a connection pool that handles stale connections or use the "autoReconnect" parameter (see "Developing Applications with MySQL Connector/J").

Also, you should be catching SQLExceptions in your application and dealing with them, rather than propagating them all the way until your application exits, this is just good programming practice. MySQL Connector/J will set the SQLState (see java.sql.SQLException.getSQLState() in your APIDOCS) to "08S01" when it encounters network-connectivity issues during the processing of a query. Your application code should then attempt to re-connect to MySQL at this point.

在客户那边,晚上时间是不会有人使用这个系统的,就造成了系统中原先没有考虑到的这个情况。

为此我试验了三种方法:1、在数据库的url中加入autoReconnect=true;2、在每次调用getSession()方法时判断session.isClosed()是否为真,若为真则调用session.reconnect();3、在经过两天,事实证明前两种方法都不起作用的情况下,我在这个页面找到了第三种方法,即不使用Hibernate内置的连接池(Hibernate强烈推荐不使用但我以前一直在用),改用C3P0连接池,这个连接池会自动处理数据库连接被关闭的情况。要使用C3P0很简单,先从Hibernate里把c3p0-0.8.3.jar复制到项目的lib目录中,再在hibernate.properties里去掉hibernate.c3p0开头的那些属性的注释(使用缺省值或自己需要的数值),这样Hibernate就会自动使用C3P0代替内置的连接池了。到目前为止前面的问题没有再出现过。

以前对Hibernate警告不要使用内置连接池作产品用途没有太放在心上,这次是一个教训,所以不论从稳定还是性能的考虑,都应该选择相对更加成熟的连接池。

update:除了连接池的原因,原先写的HibernateDAO类也有问题,在有些情况下一个session会被多个请求反复使用,现在已改正。另外,c3p0这个名字不是星球大战里那个机器人么?

posted on 2004-12-10 11:02 八进制 阅读(10482) 评论(21) 编辑 收藏

评论

#1楼 2005-01-21 09:40 raully
很好,老兄,受教了:)正被这个问题烦着,前两个办法都试了也不好使
 回复 引用   

#2楼 2005-02-21 21:40 aihua
救命贴呀! 谢谢兄台!!!!
 回复 引用   

#3楼 2005-03-06 14:31 Sammy Chan
杨枝甘露啊!正为此肝腦塗地,千谢萬谢!
 回复 引用   

#4楼 2005-06-08 09:36 taolue
景仰之情,如滔滔江水,绵绵不绝.
 回复 引用   

#5楼 2005-06-17 14:12 热望器
老兄,可不可一告诉我hibernate.properties在那 我找不到呀!
 回复 引用   

#6楼[楼主] 2005-06-17 16:10 八进制      
在你的程序里一般直接放在classes目录下。从网上下载的hibernate里会包含一个缺省的hibernate.properties文件,把它拷过来修改一下就可以用了。
 回复 引用 查看   

#7楼 2005-07-04 14:32 游客
感谢.
 回复 引用   

#8楼 2005-07-07 09:20 mickey [未注册用户]
我也遇到了这个问题。用c3p0以后发现还是不行,同样的错误。请问什么原因阿?
 回复 引用   

#9楼 2005-07-13 13:20 dps[未注册用户]
感谢呀
 回复 引用   

感谢啊,我们就遇到了个这种问题。

非常感谢你,我的QQ 22530630,希望能够和你一起研究Hibernate
 回复 引用   

#11楼 2005-07-28 12:28 xiemin[未注册用户]
楼主,我试了c3p0,可还是不行,不知道你用的是什么版本的jdbc驱动?还有mysql还要什么特殊的设置吗?谢谢
 回复 引用   

#12楼[楼主] 2005-07-28 19:57 八进制      
我的驱动是3.0.9stable,mysql上没有什么特殊的设置。
 回复 引用 查看   

用c3p0以后发现还是不行,不知道哪儿有问题
 回复 引用   

#14楼 2005-08-01 16:03 xiemin[未注册用户]
搂主可以说一下你的c3p0设置吗?谢谢
 回复 引用   

#15楼 2005-09-23 14:27 小徐[未注册用户]
我替换为C3P0后,这个问题解决了,可是又出现新的问题:有时候报:
java.sql.SQLException: You can't operate on a closed connection!!!
at com.mchange.v2.c3p0.impl.C3P0PooledConnection$ProxyConnectionInvocationHandler.invoke(C3P0PooledConnection.java:724)
at com.mchange.v2.c3p0.impl.$Proxy42.prepareStatement(Unknown Source)
at net.sf.hibernate.impl.BatcherImpl.getPreparedStatement(BatcherImpl.java:260)
at net.sf.hibernate.impl.BatcherImpl.getPreparedStatement(BatcherImpl.java:235)
at net.sf.hibernate.impl.BatcherImpl.prepareQueryStatement(BatcherImpl.java:66)
at net.sf.hibernate.loader.Loader.prepareQueryStatement(Loader.java:779)
at net.sf.hibernate.loader.Loader.doQuery(Loader.java:265)
at net.sf.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:133)
at net.sf.hibernate.loader.Loader.doList(Loader.java:1033)
at net.sf.hibernate.loader.Loader.list(Loader.java:1024)
at net.sf.hibernate.hql.QueryTranslator.list(QueryTranslator.java:854)
at net.sf.hibernate.impl.SessionImpl.find(SessionImpl.java:1553)
at net.sf.hibernate.impl.QueryImpl.list(QueryImpl.java:39)
.........
但刷新两次就又能连接上了.为什么,如何处理.
 回复 引用   

#16楼 2005-09-27 17:33 小徐[未注册用户]
换成Jboss的连接池就好了
 回复 引用   

雪中送炭!
 回复 引用   

#18楼 2006-03-20 15:12 ttof[未注册用户]
Should the driver try to re-establish stale or dead connections? If enabled the driver will throw an exception for a queries issued on a stale or dead connection, which belong to the current transaction, but will attempt reconnect before the next query issued on the connection in a new transaction. The use of this feature is not recommended, because it has side effects related to session state and data consistency when applications don'thandle SQLExceptions properly, and is only designed to be used when you are unable to configure your application to handle SQLExceptions resulting from dead andstale connections properly. Alternatively, investigate setting the MySQL wait_timeout system variable to some high value rather than the default of 8 hours.

http://dev.mysql.com/doc/refman/5.0/en/cj-configuration-properties.html

好象用了autoReconnect以后会自动重新连接的
虽然第一次执行失败了,
但是以后会自动重新连接的
 回复 引用   

请问小徐,你那个问题是怎么解决的,我现在用jboss的连接也是不行,现在出现的是这样的异常
2006-08-04 13:34:46,640 INFO [org.jboss.resource.connectionmanager.CachedConnectionManager] Closing a connection for you. Please close them yourself: org.jboss.resource.adapter.jdbc.WrappedConnection@1e91485
java.lang.Throwable: STACKTRACE
at org.jboss.resource.connectionmanager.CachedConnectionManager.registerConnection(CachedConnectionManager.java:290)
at org.jboss.resource.connectionmanager.BaseConnectionManager2.allocateConnection(BaseConnectionManager2.java:400)
at org.jboss.resource.connectionmanager.BaseConnectionManager2$ConnectionManagerProxy.allocateConnection(BaseConnectionManager2.java:812)
at org.jboss.resource.adapter.jdbc.WrapperDataSource.getConnection(WrapperDataSource.java:88)
at com.science.core.CacheManager.getConnection(Unknown Source)
at org.apache.jsp.editor.index_jsp._jspService(index_jsp.java:327)
at org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:97)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:810)
at org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:332)
at org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:314)
at org.apache.jasper.servlet.JspServlet.service(JspServlet.java:264)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:810)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:252)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:173)
at org.apache.catalina.core.ApplicationDispatcher.invoke(ApplicationDispatcher.java:672)
at org.apache.catalina.core.ApplicationDispatcher.processRequest(ApplicationDispatcher.java:463)
at org.apache.catalina.core.ApplicationDispatcher.doForward(ApplicationDispatcher.java:398)
at org.apache.catalina.core.ApplicationDispatcher.forward(ApplicationDispatcher.java:301)
at com.science.servlet.EditorServlet.doPost(Unknown Source)
at com.science.servlet.EditorServlet.doGet(Unknown Source)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:697)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:810)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:252)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:173)
at org.jboss.web.tomcat.filters.ReplyHeaderFilter.doFilter(ReplyHeaderFilter.java:96)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:202)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:173)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:213)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:178)
at org.jboss.web.tomcat.security.CustomPrincipalValve.invoke(CustomPrincipalValve.java:54)
at org.jboss.web.tomcat.security.SecurityAssociationValve.invoke(SecurityAssociationValve.java:174)
at org.jboss.web.tomcat.security.JaccContextValve.invoke(JaccContextValve.java:74)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:126)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:105)
at org.jboss.web.tomcat.tc5.jca.CachedConnectionValve.invoke(CachedConnectionValve.java:153)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:107)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:148)
at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:869)
at org.apache.coyote.http11.Http11BaseProtocol$Http11ConnectionHandler.processConnection(Http11BaseProtocol.java:664)
at org.apache.tomcat.util.net.PoolTcpEndpoint.processSocket(PoolTcpEndpoint.java:527)
at org.apache.tomcat.util.net.MasterSlaveWorkerThread.run(MasterSlaveWorkerThread.java:112)
at java.lang.Thread.run(Thread.java:595)

也还是有连接池没有被释放
 回复 引用   

#20楼 2007-06-08 10:07 gx[未注册用户]
我用的是Ibatis连mysql
在登录时,时常出现如上的错误啊,郁闷啊。
com.ibatis.dao.client.DaoException: Failed to queryForList - id [getAdminByName], parameterObject [admin]. Cause: com.ibatis.common.jdbc.exception.NestedSQLException:
--- The error occurred in com/vodone/cpms/sql/Admin.xml.
--- The error occurred while executing query.
--- Check the select * from admin where user_name = ? .
--- Check the SQL Statement (preparation failed).
--- Cause: java.sql.SQLException: No operations allowed after connection closed.

Connection was closed due to the following exception:

** BEGIN NESTED EXCEPTION **

java.sql.SQLException
MESSAGE: Communication link failure: java.io.EOFException, underlying cause: null

** BEGIN NESTED EXCEPTION **

java.io.EOFException

STACKTRACE:

java.io.EOFException
at com.mysql.jdbc.MysqlIO.readFully(MysqlIO.java:1319)
at com.mysql.jdbc.MysqlIO.reuseAndReadPacket(MysqlIO.java:1463)
at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:1854)
at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:1109)
at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:1203)
at com.mysql.jdbc.MysqlIO.sqlQuery(MysqlIO.java:1164)
at com.mysql.jdbc.Connection.execSQL(Connection.java:2087)
at com.mysql.jdbc.Connection.execSQL(Connection.java:2049)
at com.mysql.jdbc.Connection.execSQL(Connection.java:2030)
at com.mysql.jdbc.Connection.rollbackNoChecks(Connection.java:3004)
at com.mysql.jdbc.Connection.rollback(Connection.java:1458)
at com.ibatis.common.jdbc.SimpleDataSource.popConnection(SimpleDataSource.java:621)
at

** END NESTED EXCEPTION **
 回复 引用   

#21楼 2007-06-19 10:27 过客[未注册用户]
我也遇到过类似问题,把c3p0.8.x.jar换成c3p0.9.x.jar就可以了
 回复 引用