Исправление PostgreSQL: "Ошибка ввода-вывода при отправке на бэкэнд"

Я тестирую код, который обрабатывает регистрацию на веб-сайте. Код 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 выглядит следующим образом (EDIT: Иногда 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      

Ответ 1

Хотя на самом деле поздно ответить, надеюсь, что это поможет кому-то.

У меня такое же Исключение, но я подключаюсь к локальному db на том же хосте.
Причина была в связи, которая больше недействительна, и поэтому мне нужно было открыть ее снова.

Существует тег на postgresql.org, у которого есть связанная тема. Их ответ довольно схож, просто перехватывая исключение и повторно открывая соединение

PostgreSQL Версия: 8.4

Ответ 2

Я подозреваю, что ваше приложение и база данных находятся на разных компьютерах и там где-то посередине (с точки зрения состояния). Я предполагаю, что брандмауэр отключает соединение после того, как он был открыт в течение определенного времени, возможно, без трафика. Пул соединений не сможет обнаружить это, прежде чем передать вам сломанное соединение.

Единственное, что заставляет меня сомневаться в этом, это то, что он всегда происходит в одном и том же месте в коде, но если это первый запрос к базе данных в новом сеансе (или что-то в этом роде), это немыслимо, он всегда может появляться в то же место.

Ответ 3

У меня была та же проблема в тесте, но причина заключалась в вызове nextSequenceId между созданием метода PreparedStatement и метода executeUpdate, используя тот же объект Connection. Моим решением было перемещение вызова nextSequenceId в верхней части метода, и проблема исчезла.

Ответ 4

У меня такая же проблема, и я решил, что мое изменение является одним из них:

  • Ваш запрос очень большой, как:

    SELECT * FROM 'Table' WHERE id in?param

param большой список.

  • Ваш результат очень большой (например, более 4 ГБ)