postgresql Postgres -为什么忽略查询超时?

nlejzf6q  于 2022-11-23  发布在  PostgreSQL
关注(0)|答案(1)|浏览(156)

EDIT-这与Jooq无关,请参见原始问题后的EDIT部分中的详细信息。

--
我使用Jooq对PostgreSQL数据库运行了一个查询。由于我知道这个查询需要很长时间,所以我尝试设置查询超时。我尝试了几种方法,但每次的结果都是查询超时被忽略,并且查询在一分钟后失败(这是此数据库的默认超时),错误如下:canceling statement due to statement timeout。为什么会这样?如何设置查询超时?
以下是我尝试设置TO的方法:
1-

DSL.using(dataSource, SQLDialect.POSTGRES, new Settings().withQueryTimeout(600))
    .deleteFrom(...)
    ...
    .execute();

2-

DSL.using(dataSource, SQLDialect.POSTGRES)
    .deleteFrom(...)
    ...
    .queryTimeout(6000)
    .execute();

3-

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无关。
connection的类型为org.postgresql.jdbc.PgConnection
preparedStatement的类型为org.postgresql.jdbc.PgPreparedStatement

35g0bw71

35g0bw711#

这两个函数的作用是不同的。statement_timeout使数据库服务器根据PostgreSQL的计时器自行取消查询,而setQueryTimeout()使Java根据Java的计时器启动取消操作(通过打开一个单独的特定目的的数据库连接并发送一个取消请求)。由于它们是不同的机制,因此一个不会取消另一个。
要取消服务器设置,您需要执行set local statement_timeout=120000;语句。可能还有其他方法可以更改服务器设置,但setQueryTimeout()不是其中之一。

相关问题