我正在使用Java Future类来执行连接Oracle数据库的程序。但是有时查询的速度比预期的要慢。我可以通过future.cancel方法取消未来。
假设我通过future.cancel取消了Future线程。查询将在Oracle中停止执行,还是仅应用程序线程将被停止/取消,Oracle查询将继续在数据库端运行。
我们提交的将来很多,有些还很慢。.超时不会结束提交,但是只能为future.get设置,但是将来仍然按照java规范进行操作。
在这种情况下的实际行为是什么。
谢谢
答案 0 :(得分:0)
您可以尝试向数据库发送终止查询,在数据库中将使用您要终止的查询的PID,尝试使用此链接以不同的方式How to kill a running SELECT statement终止查询。
将进程放入线程,然后尝试添加类似isInterrupted()
或isAlive()
的内容以检查线程的状态,然后发送查询以终止正在运行的查询(如果已终止)。
我想到的最好的办法就是终止一个正在运行的数据库
在程序中。
答案 1 :(得分:0)
将来取消将不会终止Oracle查询。更糟糕的是,Completablefuture的cancel只会导致CancellationException使其异常完成。这不会停止提交的任务,甚至不会试图中断它。
从文档中
CompletableFuture.cancel(boolean mayInterruptIfRunning):
如果尚未完成,请使用CancellationException完成此CompletableFuture。尚未完成的从属CompletableFutures也将异常完成,并带有由此CancellationException引起的CompletionException。
mayInterruptIfRunning-此值在此实现中无效,因为不使用中断来控制处理。
您可以在数据库连接上设置超时,以在连接上使用OracleConnection.CONNECTION_PROPERTY_THIN_READ_TIMEOUT进行读取(Setting Network Timeout for JDBC connection)。这不会杀死Oracle的线程,但是会使读取的语句超时。
或使用Statement.cancel尝试取消数据库中的运行语句。 (When I call PreparedStatement.cancel() in a JDBC application, does it actually kill it in an Oracle database?)。这是为了杀死数据库执行线程,但是数据库可能并不总是尊重它。
除此之外,我建议对您的CompletableFutures使用小型FixedThreadPool执行程序来控制并行数据库线程的数量。
编辑
要在休眠会话中执行相同操作,请使用Session#cancelQuery()