PostgreSQL查询超时不会阻止JDBC客户端尝试从服务器读取数据

Mic*_*las 5 postgresql jdbc

我在使用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)
Run Code Online (Sandbox Code Playgroud)

从服务器端,我看到查询(pid 31657)运行> 30秒,但服务器检测到客户端断开连接.我认为在10分钟后服务器从JDBC驱动程序接收到"带有PID 32657的CANCEL查询"命令,但此连接在断开连接后结束:

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
Run Code Online (Sandbox Code Playgroud)

我认为这个取消来自JDBC驱动程序,但我不确定.对我来说最奇怪的是,在10分钟后,JDBC客户端仍然想要从服务器读取数据.它会挂起几个小时,直到我重新启动整个服务.

我认为有两个问题:

  1. 网络连接出现问题:服务器检测到断开连接,但客户端认为它仍然连接.

  2. 查询超时不会停止JDBC尝试从服务器读取数据.

有什么办法可以阻止我想要从服务器读取数据的挂起线程吗?

我的环境:

客户:

Java:1.8.0_92(Oracle Corporation)

PostgreSQL本机驱动程序PostgreSQL 9.4.1208

服务器:

在x86_64-pc-linux-gnu上的PostgreSQL 9.5.3,由gcc编译(Debian 4.9.2-10)4.9.2,64位