使用Tomcat连接池取消JDBC中长时间运行的查询

时间:2019-06-10 17:40:52

标签: java oracle tomcat jdbc connection-pooling

我们有一个报告应用程序,可以运行较长的查询。允许用户通过单击按钮来取消正在运行的报告。这将调用一种方法来停止报告线程并关闭其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)

0 个答案:

没有答案