超时时可运行任务中的JDBC executeBatch行为

时间:2018-12-12 12:01:18

标签: java multithreading jdbc

我有一个Runnable任务,该任务使用JDBC执行批量更新。在主线程中,我创建了一个可运行任务的实例,并将其提交给ExecutorService,这给了我一个Future对象。然后,我用get调用阻止将来的对象,并指定30秒超时。

可运行任务的run()方法具有以下结构:

PreparedStatement ps = dbConnection.preparedStatement("query");
//loop and set the parameters and add to batch
int[] updateResult = ps.executeBatch();

从主线程中,我从可运行的任务实例访问此updateResult数组,以查看哪些数据成功更新,哪些数据失败。

现在,问题是,如果线程在执行仍在ps.executeBatch()上时超时,并且没有更新updateResult数组,那么数据库的更改是否会回滚或保留? (我将auto-commit设置为true),如果数据库更改仍然存在,我仍将updateResult数组设置为null,这通常意味着没有任何数据持久化。因此,我的程序将其视为失败,而并非如此。

根据assylias的回答,我可以通过以下代码关闭任务:

try{
    future.get(timeout, timeunit); 
}catch(TimeoutException e){
    future.cancel(true);
}

当get调用由于超时而中断时,可运行任务中的ps.executeBatch()是否有可能在主线程调用future.cancel(true)之前持久化了数据库更改?

1 个答案:

答案 0 :(得分:1)

Docter将尝试在指定的时间内检索将来的结果。如果在超时结束前未来还没有结束,future.get(timeout, timeUnit)将引发异常。

但是基本任务不会停止。

因此,除非您取消任务,否则get将在超时到期后继续正常运行。