Java 如何中断使用Postgresql运行JDBC查询的线程?

Java 如何中断使用Postgresql运行JDBC查询的线程?,java,multithreading,postgresql,jdbc,Java,Multithreading,Postgresql,Jdbc,我有一个线程池,运行的任务主要是使用JDBC查询Postgresql。如果取消已提交任务的未来将取消任何正在进行的查询,这将非常方便。有没有一个简单的方法可以做到这一点?它只适用于Postgresql。您可以使用: 如果DBMS和驱动程序都支持中止SQL语句,则取消此语句对象。一个线程可以使用此方法取消另一个线程正在执行的语句 cancel()在PostgreSQL JDBC驱动程序中实现。您可以使用: 如果DBMS和驱动程序都支持中止SQL语句,则取消此语句对象。一个线程可以使用此方法取消另一

我有一个线程池,运行的任务主要是使用JDBC查询Postgresql。如果取消已提交任务的未来将取消任何正在进行的查询,这将非常方便。有没有一个简单的方法可以做到这一点?它只适用于Postgresql。

您可以使用:

如果DBMS和驱动程序都支持中止SQL语句,则取消此语句对象。一个线程可以使用此方法取消另一个线程正在执行的语句

cancel()
在PostgreSQL JDBC驱动程序中实现。

您可以使用:

如果DBMS和驱动程序都支持中止SQL语句,则取消此语句对象。一个线程可以使用此方法取消另一个线程正在执行的语句


cancel()
是在PostgreSQL JDBC驱动程序中实现的。

事实证明,Postgres JDBC连接有一个非标准的cancelQuery()方法,用于取消连接上运行的任何查询。因此,我将提交任务及其连接时返回的future包装在一起,并覆盖cancel()以调用cancelQuery()

import org.postgresql.core.BaseConnection;
私有静态类混淆实现了未来{
私人未来包装;
私有易失性连接;
公共布尔值取消(布尔值可能中断刷新){
布尔ans=wrapped.cancel(可能中断frunning);
连接con=this.con;
如果(con!=null){
试一试{
con.unwrap(BaseConnection.class).cancelQuery();
}捕获(SQLE异常){
log.error(“无法取消查询:+e”);
}
}
返回ans;
}
...

事实证明,Postgres JDBC连接有一个非标准的cancelQuery()方法,用于取消连接上运行的任何查询。因此,我将提交任务及其连接时返回的future包装在一起,并覆盖cancel()以调用cancelQuery()

import org.postgresql.core.BaseConnection;
私有静态类混淆实现了未来{
私人未来包装;
私有易失性连接;
公共布尔值取消(布尔值可能中断刷新){
布尔ans=wrapped.cancel(可能中断frunning);
连接con=this.con;
如果(con!=null){
试一试{
con.unwrap(BaseConnection.class).cancelQuery();
}捕获(SQLE异常){
log.error(“无法取消查询:+e”);
}
}
返回ans;
}
...

您的runable需要检查
线程
,这样,如果您尝试取消未来,未来可以对此做出反应,并取消它正在执行的语句问题是,当线程被中断时,线程在Postgres JDBC驱动程序代码中,特别是从套接字读取时,什么也没有发生。如果该进程没有反应,您就无能为力。我相信在这种情况下,您应该能够有某种超时+回滚逻辑,这样,如果您尝试取消未来,未来可以对此做出反应,并取消它正在执行的语句问题是,当线程被中断时,线程在Postgres JDBC驱动程序代码中,特别是从套接字读取时,什么也没有发生。如果该进程没有反应,您就无能为力。我相信在这种情况下,您应该能够有某种超时+回滚逻辑。这种方法的问题是我需要访问任务正在使用的语句。这是可能的,但很混乱。这种方法的问题是我需要访问语句正在被任务使用。这是可能的,但很混乱。您最好将增强请求作为
BaseConnection
接口应为驱动程序内部提交。公共扩展名在
org.postgresql.PGConnection
中定义。您最好将增强请求作为
BaseConnection
接口应为驱动程序提交-内部.Public扩展在
org.postgresql.PGConnection
import org.postgresql.core.BaseConnection;

private static class ConFuture<T> implements Future<T> {

    private Future<T> wrapped;
    private volatile Connection con;

    public boolean cancel(boolean mayInterruptIfRunning) {
        boolean ans = wrapped.cancel(mayInterruptIfRunning);
        Connection con = this.con;
        if (con != null) {
            try {
                con.unwrap(BaseConnection.class).cancelQuery();
            } catch (SQLException e) {
                log.error("Unable to cancel query: " + e);
            }
        }
        return ans;
    }
    ...