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