为什么PostgreSQL会忽略查询超时?



我使用jOOQ对PostgreSQL DB运行查询。因为我知道这个查询将花费很长时间,所以我尝试设置查询超时。我尝试了几种方法,但每次结果都是查询超时被忽略,并且查询在一分钟后失败(这是此DB的默认超时),错误为:&;由于语句超时&;而取消语句。为什么会出现这种情况?如何设置查询超时?

以下是我尝试设置to的方法:

1。

DSL.using(dataSource, SQLDialect.POSTGRES, new Settings().withQueryTimeout(600))
.deleteFrom(...)
...
.execute();
  • DSL.using(dataSource, SQLDialect.POSTGRES)
    .deleteFrom(...)
    ...
    .queryTimeout(6000)
    .execute();
    
  • DSLContext transactionContext = 
    DSL.using(dataSource, SQLDialect.POSTGRES, new Settings().withQueryTimeout(600));
    transactionContext.transaction(configuration ->
    {
    DSL.using(configuration).deleteFrom(...)
    ...
    .execute();
    });
    
    我被告知这与jOOQ无关,所以我做了以下测试:

    import org.apache.commons.dbcp2.*;
    import java.sql.Connection;
    import java.sql.PreparedStatement;
    ...
    ConnectionFactory connectionFactory = new DriverManagerConnectionFactory(dbURL, username, password);
    Connection connection = connectionFactory.createConnection();
    PreparedStatement preparedStatement = connection.prepareStatement("select pg_sleep(80)");
    preparedStatement.setQueryTimeout(120);
    preparedStatement.execute();
    

    此操作在一分钟后失败,并出现相同的超时错误,因此问题确实与jOOQ无关。

    connectionorg.postgresql.jdbc.PgConnection型。

    preparedStatementorg.postgresql.jdbc.PgPreparedStatement型。

    它们做不同的事情。statement_timeout使数据库服务器根据PostgreSQL的计时器自行取消查询,而setQueryTimeout()使Java根据Java的计时器启动取消(通过打开一个单独的特定于数据库的连接并发送取消请求)。因为它们是不同的机制,一个不能反命令另一个。

    要撤销服务器设置,您需要执行类似于执行语句set local statement_timeout=120000;的操作。可能还有其他方法可以更改服务器设置,但setQueryTimeout()不是其中之一。

    最新更新