Отмените длительный запрос в JDBC с помощью пула соединений Tomcat - PullRequest
1 голос
/ 10 июня 2019

У нас есть приложение для составления отчетов, которое может выполнять длинные запросы. Пользователь может отменить текущий отчет, нажав кнопку. Это вызывает метод, который останавливает поток отчетов и закрывает его соединение JDBC.

Проблема, с которой мы сталкиваемся, заключается в том, что соединение JDBC возвращается в пул Tomcat, но оно все еще используется. Поэтому, когда другой поток получает это соединение и пытается его использовать, выполнение в драйвере Oracle блокируется оставленным оператором.

Кажется, что исправлением было бы сначала вызвать метод Statement.cancel (), но некоторые указали (http://stackoverflow.com/a/659063/603516), что этот метод может не иметь немедленного эффекта.

Так, каков правильный подход? Могу ли я закрыть соединение, не возвращая его в пул? Должен ли я оставить его открытым? Я знаю, что есть некоторые настройки тайм-аута, которые я мог бы установить для соединения, но, поскольку это приложение для составления отчетов, запросы могут выполняться в течение нескольких часов, и я не чувствую себя комфортно, устанавливая какой-либо таймаут.

Может быть, один из вариантов - установить validationQueryTimeout? Но что, если соединение не проверяется перед каждым использованием?

> "Report_Worker-26" Id=104 in RUNNABLE (running in native)
>     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 oracle.net.ns.Packet.receive(Packet.java:311)
>     at oracle.net.ns.DataPacket.receive(DataPacket.java:105)
>     at oracle.net.ns.NetInputStream.getNextPacket(NetInputStream.java:305)
>     at oracle.net.ns.NetInputStream.read(NetInputStream.java:249)
>     at oracle.net.ns.NetInputStream.read(NetInputStream.java:171)
>     at oracle.net.ns.NetInputStream.read(NetInputStream.java:89)
>     at oracle.jdbc.driver.T4CSocketInputStreamWrapper.readNextPacket(T4CSocketInputStreamWrapper.java:123)
>     at oracle.jdbc.driver.T4CSocketInputStreamWrapper.read(T4CSocketInputStreamWrapper.java:79)
>     at oracle.jdbc.driver.T4CMAREngineStream.unmarshalUB1(T4CMAREngineStream.java:426)
>     at oracle.jdbc.driver.T4CTTIfun.receive(T4CTTIfun.java:390)
>     at oracle.jdbc.driver.T4CTTIfun.doRPC(T4CTTIfun.java:249)
>     at oracle.jdbc.driver.T4C8Oall.doOALL(T4C8Oall.java:566)
>     at oracle.jdbc.driver.T4CPreparedStatement.doOall8(T4CPreparedStatement.java:215)
>     at oracle.jdbc.driver.T4CPreparedStatement.doOall8(T4CPreparedStatement.java:58)
>     at oracle.jdbc.driver.T4CPreparedStatement.executeForDescribe(T4CPreparedStatement.java:776)
>     at oracle.jdbc.driver.OracleStatement.executeMaybeDescribe(OracleStatement.java:897)
>     at oracle.jdbc.driver.OracleStatement.doExecuteWithTimeout(OracleStatement.java:1034)
>     at oracle.jdbc.driver.OraclePreparedStatement.executeInternal(OraclePreparedStatement.java:3820)
>     at oracle.jdbc.driver.OraclePreparedStatement.executeQuery(OraclePreparedStatement.java:3867)
>       - locked oracle.jdbc.driver.T4CConnection@60e36e18
>     at oracle.jdbc.driver.OraclePreparedStatementWrapper.executeQuery(OraclePreparedStatementWrapper.java:1502)
> ...
> 
> "http-bio-9050-exec-17" Id=205 in BLOCKED on
> lock=oracle.jdbc.driver.T4CConnection@60e36e18
>      owned by Report_Worker-26 Id=104
>     at oracle.jdbc.driver.PhysicalConnection.createStatement(PhysicalConnection.java:3878)
>     at org.apache.tomcat.jdbc.pool.PooledConnection.validate(PooledConnection.java:453)
>     at org.apache.tomcat.jdbc.pool.PooledConnection.validate(PooledConnection.java:394)
>     at org.apache.tomcat.jdbc.pool.ConnectionPool.borrowConnection(ConnectionPool.java:775)
>     at org.apache.tomcat.jdbc.pool.ConnectionPool.borrowConnection(ConnectionPool.java:619)
>     at org.apache.tomcat.jdbc.pool.ConnectionPool.getConnection(ConnectionPool.java:188)
>     at org.apache.tomcat.jdbc.pool.DataSourceProxy.getConnection(DataSourceProxy.java:128)
...