posts - 297,  comments - 1618,  trackbacks - 0
     今天一个同事说有个系统出现java.net.SocketException MESSAGE: Broken pipe错误,问题描述是这样的:
     网站很久没有人登陆后,例如一个晚上没有登录,早上看时,出现错误,但重启Tomcat后又不再有问题,错误信息如下:
    

SQL Error: 0, SQLState: 08S01
[2007-11-20 09:14:30] 72 ERROR [org.hibernate.util.JDBCExceptionReporter]
Communications link failure due to underlying exception:

** BEGIN NESTED EXCEPTION **

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)
 at org.hibernate.jdbc.AbstractBatcher.getResultSet(AbstractBatcher.java:120)
 at org.hibernate.loader.Loader.getResultSet(Loader.java:1272)
 at org.hibernate.loader.Loader.doQuery(Loader.java:391)
 at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:218)
 at org.hibernate.loader.Loader.loadEntity(Loader.java:1345)
 at org.hibernate.loader.entity.EntityLoader.load(EntityLoader.java:116)
 at org.hibernate.loader.entity.EntityLoader.load(EntityLoader.java:101)
 at org.hibernate.persister.entity.BasicEntityPersister.load(BasicEntityPersister.java:2471)
 at org.hibernate.event.def.DefaultLoadEventListener.loadFromDatasource(DefaultLoadEventListener.java:351)
 at org.hibernate.event.def.DefaultLoadEventListener.doLoad(DefaultLoadEventListener.java:332)
 at org.hibernate.event.def.DefaultLoadEventListener.load(DefaultLoadEventListener.java:113)
 at org.hibernate.event.def.DefaultLoadEventListener.proxyOrLoad(DefaultLoadEventListener.java:151)
 at org.hibernate.event.def.DefaultLoadEventListener.onLoad(DefaultLoadEventListener.java:79)
 at org.hibernate.impl.SessionImpl.get(SessionImpl.java:621)
 at org.hibernate.impl.SessionImpl.get(SessionImpl.java:614)
 at com.cotel.dao.BaseDao.getObject(BaseDao.java:180)
 at com.cotel.wfsgprs.bean.systemmanage.LoginBean.login(LoginBean.java:61)
 at com.cotel.wfsgprs.struts.action.login.LoginAction.login(LoginAction.java:70)
 at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
 at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
 at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
 at java.lang.reflect.Method.invoke(Method.java:585)
 at org.apache.struts.actions.DispatchAction.dispatchMethod(DispatchAction.java:280)
 at org.apache.struts.actions.DispatchAction.execute(DispatchAction.java:216)
 at org.apache.struts.action.RequestProcessor.processActionPerform(RequestProcessor.java:484)
 at org.apache.struts.action.RequestProcessor.process(RequestProcessor.java:274)
 at org.apache.struts.action.ActionServlet.process(ActionServlet.java:1482)
 at org.apache.struts.action.ActionServlet.doPost(ActionServlet.java:525)
 at javax.servlet.http.HttpServlet.service(HttpServlet.java:709)
 at javax.servlet.http.HttpServlet.service(HttpServlet.java:802)
 at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:237)
 at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:157)
 at org.apache.catalina.core.ApplicationDispatcher.invoke(ApplicationDispatcher.java:704)
 at org.apache.catalina.core.ApplicationDispatcher.processRequest(ApplicationDispatcher.java:474)
 at org.apache.catalina.core.ApplicationDispatcher.doForward(ApplicationDispatcher.java:409)
 at org.apache.catalina.core.ApplicationDispatcher.forward(ApplicationDispatcher.java:312)
 at com.cotel.util.ValidationFilter.doFilter(ValidationFilter.java:60)
 at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:186)
 at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:157)
 at com.cotel.util.PagingFilter.doFilter(PagingFilter.java:42)
 at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:186)
 at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:157)
 at com.cotel.util.EncodingFilter.doFilter(EncodingFilter.java:28)
 at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:186)
 at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:157)
 at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:214)
 at org.apache.catalina.core.StandardValveContext.invokeNext(StandardValveContext.java:104)
 at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:520)
 at org.apache.catalina.core.StandardContextValve.invokeInternal(StandardContextValve.java:198)
 at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:152)
 at org.apache.catalina.core.StandardValveContext.invokeNext(StandardValveContext.java:104)
 at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:520)
 at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:137)
 at org.apache.catalina.core.StandardValveContext.invokeNext(StandardValveContext.java:104)
 at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:118)
 at org.apache.catalina.core.StandardValveContext.invokeNext(StandardValveContext.java:102)
 at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:520)
 at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
 at org.apache.catalina.core.StandardValveContext.invokeNext(StandardValveContext.java:104)
 at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:520)
 at org.apache.catalina.core.ContainerBase.invoke(ContainerBase.java:929)
 at org.apache.coyote.tomcat5.CoyoteAdapter.service(CoyoteAdapter.java:160)
 at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:799)
 at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.processConnection(Http11Protocol.java:705)
 at org.apache.tomcat.util.net.TcpWorkerThread.runIt(PoolTcpEndpoint.java:577)
 at org.apache.tomcat.util.threads.ThreadPool$ControlRunnable.run(ThreadPool.java:683)
 at java.lang.Thread.run(Thread.java:595)


** END NESTED EXCEPTION **

       后会自动关闭已打开的连接,再问了一下,他们用的不是c3p0的数据源,建议他们改成c3p0的数据源,明天就能看到是不是由于这个原因引起的,特此记录。
       找到解决方案的一篇文章:http://wooce.sharera.com/blog/BlogTopic/35599.htm
       该问题的解决方案摘录如下:
       06/05/15:
Q:  用hibernate + mysql数据库, 出现以下问题: 
Communication link failure: java.net.SocketException, underlying cause: Broken pipe: Broken pipe 
** BEGIN NESTED EXCEPTION ** java.net.SocketException MESSAGE: Broken pipe: Broken pipe 
STACKTRACE: java.net.SocketException: Broken pipe: Broken pipe
at java.net.SocketInputStream.socketRead0(Native Method)
at java.net.SocketInputStream.read(SocketInputStream.java:116)
at java.io.BufferedInputStream.fill(BufferedInputStream.java:183)
at java.io.BufferedInputStream.read(BufferedInputStream.java:201)
at com.mysql.jdbc.MysqlIO.reuseAndReadPacket(MysqlIO.java:1399)
at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:1775)
at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:1020)
at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:1109)
at com.mysql.jdbc.MysqlIO.sqlQuery(MysqlIO.java:1070)
at com.mysql.jdbc.Connection.execSQL(Connection.java:2027)
at com.mysql.jdbc.Connection.execSQL(Connection.java:1984)
at com.mysql.jdbc.Statement.executeQuery(Statement.java:1152) 
A:   
1.  Mysql在经过8小时不使用后会自动关闭已打开的连接,摘录原文如下: 
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.
2.  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以后会自动重新连接的
虽然第一次执行失败了,
但是以后会自动重新连接的
3.  在这个页面找到了第三种方法,即不使用Hibernate内置的连接池(Hibernate强烈推荐不使用但我以前一直在用),改用C3P0连接池,这个连接池会自动处理数据库连接被关闭的情况。要使用C3P0很简单,先从Hibernate里把c3p0-0.8.3.jar复制到项目的lib目录中,再在hibernate.properties里去掉hibernate.c3p0开头的那些属性的注释(使用缺省值或自己需要的数值),这样Hibernate就会自动使用C3P0代替内置的连接池了。到目前为止前面的问题没有再出现过。

以前对Hibernate警告不要使用内置连接池作产品用途没有太放在心上,这次是一个教训,所以不论从稳定还是性能的考虑,都应该选择相对更加成熟的连接池。
4.  在服务器上过期的‘Waittimeout’基本上是服务器给与的强制性网络故障。你通过把‘Waittimeout’设置的高点儿就可以改正它,尽管如此,作为一个开发者,你的代码应该包含相关的异常处理并采取适当的恢复措施,不要都把它们传到调用堆中。

    在转贴一下在hibernate中设置c3p0数据源的方法,原文地址:http://www.lifevv.com/tenyo/doc/20070605102040991.html
     内容如下:
    c3p0为open source的JDBC连接池,随hibernate一起发布。本文介绍了怎么在hibernate里配置使用c3p0。
c3p0连接池的配置非常简单,只需要在hibernate.cfg.xml里增加:

        <!-- configuration pool -->
        <property name="c3p0.acquire_increment">1</property>
        <property name="c3p0.idle_test_period">100</property> <!-- seconds -->
        <property name="c3p0.max_size">5</property>
        <property name="c3p0.max_statements">0</property>
        <property name="c3p0.min_size">2</property>
        <property name="c3p0.timeout">90</property> <!-- seconds -->

另外,还需要在CLASS_PATH里加上c3p0-x.x.x.jar文件(x.x.x为版本号),c3p0-x.x.x.jar文件随hibernate一起发布,你可以在其lib目录下找到该文件。

配置好之后,hibernate便会自动使用c3p0的连接池:C3P0ConnectionProvider

posted on 2007-11-26 11:16 阿蜜果 阅读(7532) 评论(0)  编辑  收藏 所属分类: MySql

只有注册用户登录后才能发表评论。


网站导航:
 
<2007年11月>
28293031123
45678910
11121314151617
18192021222324
2526272829301
2345678

      生活将我们磨圆,是为了让我们滚得更远——“圆”来如此。
      我的作品:
      玩转Axure RP  (2015年12月出版)
      

      Power Designer系统分析与建模实战  (2015年7月出版)
      
     Struts2+Hibernate3+Spring2   (2010年5月出版)
     

留言簿(262)

随笔分类

随笔档案

文章分类

相册

关注blog

积分与排名

  • 积分 - 2285120
  • 排名 - 3

最新评论

阅读排行榜

评论排行榜