我在新线程中开始了一些进程:
FutureTask<?> futureTask = new FutureTask<Void>(() -> {
startSomeProcess();
}, null);
在 startSomeProcess
方法中,我为每个项目生成报告:
for (Item item : items) {
if (Thread.interrupted()) {
logger.info("currentThread isInterrupted");
return;
}
generateReport(item);
}
在 generateReport()
方法中,我对数据库执行一些选择并从 ResultSet
生成 excel 报告:
try (PreparedStatement ps = conn.prepareStatement(query.toString(),
ResultSet.TYPE_SCROLL_INSENSITIVE)) {
ResultSet rs = ps.executeQuery();
//and fill excel from rs
...
但是我的 ps.executeQuery();
可以执行很长时间(1 秒 - 999999h。
我有取消按钮。如果它按下我做这个
futureTask.cancel(true);
并在 startSomeProcess();
方法中检查异常。但我无法检查和中断 ps.executeQuery();
。当我使 futureTask.cancel(true);
此 executeQuery
抛出异常时。但是我没有配置这个。它是自动的。
我的报价:当我中断线程时 - 我可以或让我自己中断对数据库的查询,还是它只是发生而我只需要处理错误?
编辑:
用户发送命令 - “取消报告生成”。我找到 futureTask 并调用 cancel()
方法。并打破构建报告。但是如果 ps.executeQuery();已经开始-我不知道怎么打破它
最佳答案
My questions: when I interrupt the thread - Can I or do I have myself interrupt the query to the database, or it just happens and I have to handle the error only?
中断线程只会在线程上设置一个标志,这只会导致那些抛出 InterruptedException
的方法这样做。在这种情况下,SQL 方法不会抛出 InterruptedException
,因此仅调用 future.cancel(true)
将不起作用。
如果您试图取消正在运行的 SQL 查询,那么您将需要在 JDBC 级别执行 canceling the underlying Statement
.引用 Statement.cancel()
的 javadocs:
Cancels this Statement object if both the DBMS and driver support aborting an SQL statement. This method can be used by one thread to cancel a statement that is being executed by another thread.
所以在您的情况下,这意味着另一个线程将不得不取消您的 ps
。我将创建一个对象来包装您的 generateReport()
方法,该方法将 PreparedStatement ps
放入 volatile
字段中。然后,当该方法执行 ps
时,它会从字段执行此操作,并且另一个线程可以在调用 ps.cancel()的对象上调用
.cancel()
请务必注意,查询取消依赖于 SQL 数据库和 JDBC 驱动程序。并非所有数据库都支持它。
关于java - 数据库查询中断,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41483480/