2013-06-24 86 views
11

我測試了一些處理註冊到網站的代碼。 Java代碼如下(節選):PostgreSQL異常:「發送到後端時發生I/O錯誤」

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的版本是23年8月1日

知道的任何幫助或建議。堆棧跟蹤如下(編輯:有時候堆棧跟蹤說通過流閉,有時關閉socket如下引起):

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  
+0

您是否正在創建單個數據庫連接並將其保持打開很長一段時間? – DaveH

+0

服務器正在關閉套接字,可能是由於空閒超時。 –

回答

3

我懷疑你的應用程序和數據庫都在不同的機器,有一個(有狀態的)防火牆中間某個地方。我的猜測是,防火牆在打開一段時間後可能會丟失連接,可能沒有流量。在連接斷開之前,連接池將無法檢測到該情況。

唯一讓我懷疑的是,它總是在代碼中的同一個地方發生,但如果這是第一次在新會話中進行數據庫查詢(或類似的事情),它並不是不可思議的,它總是會出現在同一個地方。

+0

感謝您的回答。 @Dave - 我已經嘗試了兩種方法,在查詢之前打開一個新的連接,並且也將它從以前的查詢中打開。這個問題無論如何都會重現。 – James

+0

但是來自連接池的「新」連接還是實際上是新的?如果它來自游泳池,那麼當你拿到它時可能會斷開連接。 – wobblycogs

+0

目前我沒有使用連接池Wobbly。 – James

8

儘管回答真的很遲,但我希望這可以幫助某人。

我得到了同樣的異常,但我連接到同一主機上的本地數據庫。
原因是連接,這是無效的,所以我需要再次打開它。

在postgresql.org上有一個ticket,它有一個相關的主題。他們的答案是非常相似的,由剛捕獲異常並重新打開連接

PostgreSQL的版本:8.4

+0

我只是有同樣的錯誤,運行在8.3.x上 – momomo

+0

同樣在9.3.2本地主機上(從一個java jar通過命令行調用) –

+0

我也遇到同樣的問題。但是我在想如何讓連接失效? – apm

0

我曾在一個測試同樣的問題,但原因是在一個nextSequenceId的之間的呼叫使用相同的Connection對象創建PreparedStatement和executeUpdate方法調用。 我的解決方案是在方法的頂部調用nextSequenceId,並且問題消失。

相關問題