我的多线程应用程序中存在使用JDBC PostgreSQL驱动程序的问题。有时它会挂起很长时间,对各种数据库进行各种查询。要停止此类挂起,我将查询超时设置为10分钟,但是从我的应用程序中它不起作用,在此之后它不会返回。
这种挂起线程的jstack看起来像:
"srv_thead_160621090411" #1560 prio=5 os_prio=0 tid=0x00007f0d24001800 nid=0x150f runnable [0x00007f0c83ffd000]
java.lang.Thread.State: RUNNABLE
at java.net.SocketInputStream.socketRead0(Native Method)
at java.net.SocketInputStream.socketRead(SocketInputStream.java:116)
at java.net.SocketInputStream.read(SocketInputStream.java:170)
at java.net.SocketInputStream.read(SocketInputStream.java:141)
at org.postgresql.core.VisibleBufferedInputStream.readMore(VisibleBufferedInputStream.java:143)
at org.postgresql.core.VisibleBufferedInputStream.ensureBytes(VisibleBufferedInputStream.java:112)
at org.postgresql.core.VisibleBufferedInputStream.read(VisibleBufferedInputStream.java:70)
at org.postgresql.core.PGStream.ReceiveChar(PGStream.java:283)
at org.postgresql.core.v3.QueryExecutorImpl.processResults(QueryExecutorImpl.java:1799)
at org.postgresql.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.java:200)
- locked <0x00000005dc2f9f88> (a org.postgresql.core.v3.QueryExecutorImpl)
at org.postgresql.jdbc.PgStatement.execute(PgStatement.java:424)
at org.postgresql.jdbc.PgPreparedStatement.executeWithFlags(PgPreparedStatement.java:161)
at org.postgresql.jdbc.PgPreparedStatement.executeQuery(PgPreparedStatement.java:114)
从服务器端,我看到查询(pid 31657)正在运行&gt; 30秒,但服务器检测到客户端断开连接。我认为10分钟后服务器收到&#34; CANCEL查询PID 32657&#34;来自JDBC驱动程序的命令,但此连接在断开连接后结束:
2016-06-21 07:05:23.340 CEST [31657]: [1-1] postgres [unknown] 192.168.1.124(58729) dbtest %LOG: duration: 30689.838 ms execute <unnamed>: SELECT MAX(do_nr) + 1 AS numer FROM dokumenty WHERE (do_typ = 'WZ' or upper(do_typ) = upper('WZ_tmp')) AND do_dataw BETWEEN '2016-01-01 00:00:00' AND '2016-12-31 00:00:00' AND do_magazyn = 29
2016-06-21 07:05:23.340 CEST [31657]: [2-1] postgres [unknown] 192.168.1.124(58729) dbtest %LOG: could not receive data from client: Connection reset by peer
2016-06-21 07:05:23.340 CEST [31657]: [3-1] postgres [unknown] 192.168.1.124(58729) dbtest %LOG: unexpected EOF on client connection with an open transaction
2016-06-21 07:09:24.107 CEST [21]: [8151-1] %LOG: checkpoint starting: time
2016-06-21 07:14:52.620 CEST [31703]: [1-1] [unknown] [unknown] 192.168.1.124(58860) [unknown] %LOG: PID 31657 in cancel request did not match any process
我认为这个取消来自JDBC驱动程序,但我不确定。对我来说最奇怪的是,在10分钟后,JDBC客户端仍然想要从服务器读取数据。它会挂起几个小时,直到我重新启动整个服务。
我认为有两个问题:
网络连接出现问题:服务器检测到断开,但客户认为它仍然连接。
查询超时不会停止JDBC尝试从服务器读取数据。
我能做些什么来阻止想要从服务器读取数据的挂起线程吗?
我的环境:
客户端:
Java:1.8.0_92(Oracle Corporation)
PostgreSQL Native Driver PostgreSQL 9.4.1208
服务器:
x86_64-pc-linux-gnu上的PostgreSQL 9.5.3,由gcc编译(Debian 4.9.2-10)4.9.2,64位