2013-06-24 10 views
11

Sto testando un codice che elabora la registrazione a un sito Web. Il codice Java è la seguente (estratto):Eccezione PostgreSQL: "Si è verificato un errore I/O durante l'invio al back-end"

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..... 

maggior parte del tempo il processo viene eseguito senza alcun problema, ma io sono sempre un problema intermittente in cui non riesce a causa di connessione al database si sta chiudendo. Ogni volta che fallisce, fallisce allo stesso punto - quando si esegue la dichiarazione preparata sopra (che controlla se l'email inviata è già nel database ovviamente).

versione di Postgres è 8.1.23

Qualsiasi aiuto o suggerimenti apprezzato. Stacktrace è la seguente (EDIT: A volte lo stacktrace dice causato da Stream chiusa, e talvolta Socket chiusa come sotto):

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

Si sta creando una singola connessione al database e mantenendola aperta per un lungo periodo di tempo? – DaveH

+0

Il socket viene chiuso dal server, probabilmente da un timeout di inattività. –

risposta

3

Ho il sospetto che l'applicazione e il database sono su macchine diverse e c'è una (stateful) firewall da qualche parte nel mezzo. La mia ipotesi è che il firewall stia lasciando cadere la connessione dopo che è stata aperta per un certo periodo di tempo, forse senza traffico su di essa. Il pool di connessioni non sarebbe in grado di rilevarlo prima di consegnarti una connessione interrotta.

L'unica cosa che mi fa dubitare è che accade sempre nello stesso posto nel codice, ma se quella è la prima query del database in una nuova sessione (o qualcosa del genere) non è inconcepibile che possa sempre apparire in lo stesso posto.

+0

Grazie per le vostre risposte. @Dave - Ho provato in entrambi i modi, aprendo una nuova connessione prima della query e lasciandola aperta da una query precedente. Il problema si riproduce in entrambi i modi. – James

+0

Ma la "nuova" connessione proviene da un pool di connessioni o è davvero davvero nuova? Se proviene da un pool, è possibile che la connessione sia stata interrotta quando l'hai ricevuta. – wobblycogs

+0

Attualmente non sto usando un pool di connessione traballante. – James

8

Anche se è davvero tardi per rispondere, spero che questo possa aiutare qualcuno.

Ho ottenuto la stessa eccezione, ma mi collego a un db locale sullo stesso host.
Il motivo era la connessione, che non era più valida e quindi avevo bisogno di aprirlo di nuovo.

C'è un ticket su postgresql.org che ha un argomento correlato. La loro risposta è piuttosto simile, semplicemente catturare l'eccezione e riaprire la connessione

PostgreSQL Version: 8.4

+0

Ho appena avuto lo stesso errore, in esecuzione su 8.3.x – momomo

+0

Lo stesso su 9.3.2 su localhost (da un jar java chiamato tramite la riga di comando) –

+0

Ho anche lo stesso problema. Ma mi chiedo come la connessione non sia più valida? – apm

0

Ho avuto lo stesso problema in un test, ma il motivo era nella chiamata di un nextSequenceId tra il creazione di una PreparedStatement e della chiamata al metodo executeUpdate, utilizzando lo stesso oggetto Connection. La mia soluzione è stata spostare la chiamata di nextSequenceId nella parte superiore del metodo e il problema è scomparso.

Problemi correlati