我正在测试一些处理网站注册的代码。 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
答案 0 :(得分:10)
虽然回答真的很晚,但我希望这可能会对某人有所帮助。
我得到了相同的异常,但我连接到同一主机上的本地数据库。
原因是连接不再有效,所以我需要再打开它。
postgresql.org上有一个ticket,它有一个相关的主题。他们的答案非常相似,只需捕获异常并重新打开连接
PostgreSQL版本:8.4
答案 1 :(得分:3)
我怀疑你的应用程序和数据库在不同的机器上,并且介于两者之间的某个(有状态的)防火墙。我的猜测是,防火墙在打开一段时间之后可能会丢失连接,也许没有流量。在断开连接之前,连接池将无法检测到此情况。
唯一让我怀疑的是,它总是发生在代码中的同一个地方,但如果这是新会话中的第一个数据库查询(或类似的东西),它总是出现在同一个地方。
答案 2 :(得分:0)
我在测试中遇到了同样的问题,但原因是在使用相同的Connection对象创建PreparedStatement和executeUpdate方法调用之间调用nextSequenceId。 我的解决方案是将nextSequenceId的调用移到方法的顶部,问题就消失了。
答案 3 :(得分:0)
我遇到了同样的问题,并且解决了我的问题:
您的查询非常大,例如:
SELECT * FROM 'Table' WHERE id in ?param
param
是大列表。
答案 4 :(得分:0)
这大部分适用于开发环境。
如果有人最近遇到了这个问题,并且同时在Ubuntu 19.10下使用了docker v19.03.5,它会中断某些网络管理器配置的网络连接。我没有机会详细调试此问题,但是如果您遇到此问题,我强烈建议您尝试
$ sudo service docker stop
再给连接一个镜头。
像魅力一样为我工作。