Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/315.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何调用java.sql.Connection::abort?_Java_Jdbc_Prepared Statement_Swingworker - Fatal编程技术网

如何调用java.sql.Connection::abort?

如何调用java.sql.Connection::abort?,java,jdbc,prepared-statement,swingworker,Java,Jdbc,Prepared Statement,Swingworker,我想写一个SwingWorker,当用户取消任务时,它:1)取消PreparedStatement,2)中止连接 下面是一些代码来说明: class Task extends SwingWorker<Void, Void> { Connection conn; PreparedStatement p_stmt; @Override protected Void doInBackground() throws Exception { R

我想写一个
SwingWorker
,当用户取消任务时,它:1)取消
PreparedStatement
,2)中止
连接

下面是一些代码来说明:

class Task extends SwingWorker<Void, Void> {

    Connection conn;
    PreparedStatement p_stmt;
    @Override
    protected Void doInBackground() throws Exception {
        ResultSet results = p_stmt.executeQuery();
        while(results.next()) {
            if(isCancelled())
                return;
        }
        return null;
    }

    void cancell() {
        cancel(true);
        try {
            p_stmt.cancel();
            conn.abort(/* How do I properly implement Executor? */);
        } catch (SQLException e) {
            handleError(e);
        }
    }

    @Override
    protected void done() {
        try {
            get();
        } catch (ExecutionException | InterruptedException e) {
            handleError(e);
        }
    }
}

static void handleError(Exception e) {
    // ...
}

这是我感兴趣的产品线。我应该向
Connection::abort
传递什么?

您需要在此处提供
执行器的任何实现。例如,这可以是由的方法之一创建的
Executors.newSingleThreadPool()
。您也可以使用,例如由
ForkJoinPool.commonPool()
返回的公共池,但它也可以像使用lambda为每个传递的可运行线程创建新线程一样基本:

connection.abort(runnable -> new Thread(runnable).start())
在清理完成之前,您甚至可以在当前线程中阻止所有内容:

connection.abort(Runnable::run)
每种方法都有各自的优缺点,不幸的是,很难提供好的建议,因为JDBC规范不清楚如何使用
Executor
。例如,驱动程序应该在从
abort
返回之前将所有清理任务添加到执行器(Javadoc中的措辞暗示了这一点,但可以解释),还是可以在清理过程中自由地异步添加任务?清理任务在执行时间等方面的表现应如何

如果您创建一个
执行器
,专门用于使用
Executors.newSingleThreadPool()
调用abort,则最终需要将其关闭,否则会导致线程泄漏,但如果abort clean tasks异步添加新任务,则没有明确定义的时间可以关闭Executor服务(或者您可能关闭得太早了)。这可能表明您应该在应用程序的生命周期中使用一个固定线程池,其中可能包含多个线程,而不是专门为调用中止而创建它

另一方面,如果您使用公共fork/join池,那么如果添加了大量任务,或者如果任务长时间运行,您可能会影响应用程序中也使用它的其他部分

如果驱动程序创建大量任务,我提供的第一个lambda可能会导致创建大量线程;如果驱动程序希望异步运行,我提供的第二个lambda可能会导致长时间等待,甚至可能导致错误行为

换句话说,这有点让人头疼



我将对一些JDBC驱动程序进行检查,看看是否有更好的基于实际实现的建议;不过可能需要一些时间。

为什么要调用
abort(…)
而不是
.close()
?也许我应该问另一个这样的问题,但有什么区别,哪一个更可取?老实说,我从未见过使用
.abort(…)
,只见过
.close()
。我相信abort方法是最近添加的Java 7。我之所以这样问是因为我当前的
SwingWorker
实现取消的速度不够快(即,在用户取消后查询运行几秒钟)因此,我希望深入了解取消/中止过程,以尽量减少不必要的活动。听起来不错。很高兴知道正确回答这个问题关系重大。我的具体驱动因素是Oracle OJDBC6。我实现了解决方案(
.conn.abort(Runnable::run);
),每次取消时都会出错(
java.lang.AbstractMethodError:oracle.jdbc.driver.T4CConnection.abort(Ljava/util/concurrent/Executor;)V
)。堆栈跟踪的最后一行是我的代码(即堆栈跟踪不进入任何库)。
runnable->new Thread(runnable).start()
产生相同的结果error@ryvantage
AbstractMethodError
表示该方法在实现中不存在。JDBC 4.1(Java 7)中引入了
abort
方法,在Oracle使用的命名约定中,ojdbc6.jar中的
6
表示驱动程序用于Java 6(JDBC 4),因此,
abort
方法不存在。您需要将驱动程序更新为ojdbc7或ojdbc8版本(至少,我假设Oracle在ojdbc7.jar和ojdbc8.jar中实现了它)。
connection.abort(Runnable::run)