24

Web サイトへの登録を処理するコードをテストしています。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 です

ヘルプや提案をいただければ幸いです。スタックトレースは次のとおりです(編集:スタックトレースは、ストリームが閉じられたことが原因であると言う場合があり、以下のようにソケットが閉じられている場合もあります):

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      
4

6 に答える 6

20

答えるのが本当に遅いですが、これが誰かの助けになることを願っています。

同じ例外が発生しましたが、同じホストのローカル データベースに接続しています。
その理由は、接続が無効になったため、再度開く必要があったためです。

関連トピックがある postgresql.orgのチケットがあります。彼らの答えは、例外をキャッチして接続を再度開くだけで、かなり似ています。

PostgreSQL バージョン: 8.4

于 2015-02-17T15:51:07.383 に答える
8

あなたのアプリケーションとデータベースは別のマシンにあり、その間に (ステートフルな) ファイアウォールがあると思われます。私の推測では、おそらくトラフィックがない状態で一定時間開いた後、ファイアウォールが接続をドロップしていると思われます。接続プールは、切断された接続を渡す前にこれを検出できません。

これを疑う唯一のことは、コードの同じ場所で常に発生しているということですが、それが新しいセッション (またはそのようなもの) の最初のデータベースクエリである場合、常に同じ場所に表示される可能性があることは考えられません。

于 2013-06-24T21:39:09.777 に答える
1

テストで同じ問題が発生しましたが、その理由は、同じ Connection オブジェクトを使用して、PreparedStatement の作成と executeUpdate メソッド呼び出しの間の nextSequenceId の呼び出しにありました。私の解決策は、 nextSequenceId の呼び出しをメソッドの先頭に移動することで、問題はなくなりました。

于 2016-08-24T20:10:39.950 に答える
1

私は同じ問題を抱えており、私の変更を解決したのはそれらのいずれかです:

  • あなたのクエリは次のように非常に大きいです:

    SELECT * FROM 'Table' WHERE id in ?param

paramは大きなリストです。

  • 結果が非常に大きい (たとえば、4 GIG を超える)
于 2019-06-21T20:48:58.817 に答える