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

gt0wga4j  于 2023-01-29  发布在  Java
关注(0)|答案(8)|浏览(780)

我正在测试一些处理网站注册的代码。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
3okqufwl

3okqufwl1#

我在PostgreSQL 8.4中也遇到了同样的异常,但是我连接到了同一主机上的本地数据库,原因是连接无效,所以我需要再次打开它。
www.example.com上有一个ticketpostgresql.org,它有一个相关的主题,他们的答案非常相似,只是捕捉异常并重新打开连接

sz81bmfz

sz81bmfz2#

我怀疑你的应用程序和数据库在不同的机器上,并且在它们之间有一个(有状态的)防火墙。我猜防火墙在连接打开一段时间后会断开连接,可能是因为连接上没有流量。连接池在给你一个断开的连接之前无法检测到这一点。
唯一让我怀疑这一点的是,它总是发生在代码中的同一个地方,但如果这是新会话中的第一个数据库查询(或类似的东西),它可能总是出现在同一个地方,这并不是不可想象的。

ahy6op9u

ahy6op9u3#

我得到了相同的异常。
在我的例子中,由于一些查询大量使用内存,我的数据库正在重新启动,这就是为什么我在重新启动数据库的过程中得到这个错误。
解决方案:我优化了查询。

ru9i0ody

ru9i0ody4#

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

mqkwyuun

mqkwyuun5#

我有相同的问题,并解决了我的变更是其中任何一个:

  • 您的查询非常大,例如:

SELECT * FROM 'Table' WHERE id in ?param
param是大列表。

  • 您的结果非常大(例如超过4 GIG)
jgwigjjp

jgwigjjp6#

我们正在Docker容器中使用PostgreSQL 13.5,也有同样的异常。将容器的内存大小加倍可以解决这个问题。

oug3syen

oug3syen7#

如果您使用的是连接池,则可以设置类似“SELECT 1”的测试查询-这将有助于确保在执行查询之前池中的连接已准备就绪。Spring Boot JPA - configuring auto reconnect
数据源示例:

basicDataSource.testOnBorrow = true
 basicDataSource.validationQuery = "SELECT 1"

我注意到这个问题最经常后,应用程序是坐在没有太多的行动,但我认为它一般可以发生在一整天如上所述。

oug3syen

oug3syen8#

这适用于大多数开发环境。

如果有人最近遇到了这个问题,同时在Ubuntu 19.10下使用Docker v19.03.5,它往往会中断一些网络管理器配置的网络连接。我还没有机会详细调试这个问题,但如果你遇到这个问题,我强烈建议尝试

$ sudo service docker stop

再给予他们一次机会。
对我来说就像一个护身符。

相关问题