IT-Swarm.Net

PostgreSQL的异常:“发送到后端时发生I/O错误”

我正在测试一些处理网站注册的代码。 Java代码如下(摘录):

if (request.getParameter("method").equals("checkEmail")){
            String email= request.getParameter("email");
            ResultSet rs =null;
            PreparedStatement ps = db.prepareStatement(query);
            ps.setString(1, email);
            rs = ps.executeQuery();             
            if(rs.next()){ 
                            //email already present in Db 
            } else {
                            //proceed with registration.....

大多数情况下,该过程执行没有任何问题,但我遇到了一个间歇性问题,因为它与数据库的连接正在关闭。每次失败时,它都会在同一点失败 - 运行上面准备好的语句(检查提交的电子邮件是否已经显然在数据库中)。.

Postgres的版本是8.1.23

任何帮助或建议表示赞赏。 Stacktrace如下(编辑:有时Stacktrace说由Stream Closed导致,有时Socket Closed如下):

13:53:00,973 ERROR Registration:334 - org.postgresql.util.PSQLException: An I/O error occured while sending to the backend.

  at org.postgresql.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.Java:283)
  at org.postgresql.jdbc2.AbstractJdbc2Statement.execute(AbstractJdbc2Statement.Java:479
  at org.postgresql.jdbc2.AbstractJdbc2Statement.executeWithFlags(AbstractJdbc2Statement.Java:367)
  at org.postgresql.jdbc2.AbstractJdbc2Statement.executeQuery(AbstractJdbc2Statement.Java:271)
  at Registration.doPost(Registration.Java:113)
  at javax.servlet.http.HttpServlet.service(HttpServlet.Java:637)
  at javax.servlet.http.HttpServlet.service(HttpServlet.Java:717)
  at org.Apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.Java:290)
  at org.Apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.Java:206)
  at org.Apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.Java:233)
  at org.Apache.catalina.core.StandardContextValve.invoke(StandardContextValve.Java:191)
  at org.Apache.catalina.core.StandardHostValve.invoke(StandardHostValve.Java:128)
  at org.Apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.Java:102)
  at org.Apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.Java:567)
  at org.Apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.Java:109)
  at org.Apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.Java:293)
  at org.Apache.jk.server.JkCoyoteHandler.invoke(JkCoyoteHandler.Java:190)
  at org.Apache.jk.common.HandlerRequest.invoke(HandlerRequest.Java:291)
  at org.Apache.jk.common.ChannelSocket.invoke(ChannelSocket.Java:769)
  at org.Apache.jk.common.ChannelSocket.processConnection(ChannelSocket.Java:698)
  at org.Apache.jk.common.ChannelSocket$SocketConnection.runIt(ChannelSocket.Java:891)
  at org.Apache.Tomcat.util.threads.ThreadPool$ControlRunnable.run(ThreadPool.Java:690)
  at Java.lang.Thread.run(Thread.Java:595)

Caused by: Java.net.SocketException: Socket closed

  at Java.net.SocketInputStream.socketRead0(Native Method)
  at Java.net.SocketInputStream.read(SocketInputStream.Java:129)
  at org.postgresql.core.VisibleBufferedInputStream.readMore(VisibleBufferedInputStream.Java:135)
  at org.postgresql.core.VisibleBufferedInputStream.ensureBytes(VisibleBufferedInputStream.Java:104)
  at org.postgresql.core.VisibleBufferedInputStream.read(VisibleBufferedInputStream.Java:73)
  at org.postgresql.core.PGStream.ReceiveChar(PGStream.Java:259)
  at org.postgresql.core.v3.QueryExecutorImpl.processResults(QueryExecutorImpl.Java:1620)
  at org.postgresql.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.Java:257)
    ... 22 more      
12
James

虽然回答真的很晚,但我希望这可能对某些人有所帮助。.

我得到了相同的异常,但我连接到同一主机上的本地数据库。.
原因是连接,这是无效的,所以我需要再打开它。.

Postgresql.org上有一个 ticket ,它有一个相关的主题。他们的答案非常相似,只需捕获异常并重新打开连接即可

PostgreSQL版本:8.4

9
David Artmann

我怀疑你的应用程序和数据库在不同的机器上,并且介于两者之间的某个(有状态的)防火墙。我的猜测是,防火墙在打开一段时间之后可能会丢失连接,也许没有流量。在断开连接之前,连接池将无法检测到此情况。.

唯一让我怀疑的是,它总是发生在代码中的相同位置,但如果这是新会话中的第一个数据库查询(或类似的东西),那么它总是出现在同一个地方并不是不可想象的。.

3
wobblycogs

我在测试中遇到了同样的问题,但原因是在使用相同的Connection对象创建PreparedStatement和executeUpdate方法调用之间调用nextSequenceId。我的解决方案是在方法的顶部移动nextSequenceId的调用,问题消失了。.

0
Francisco Cifuentes