【问题标题】:Execute a query but get an error if it is in waiting state for too long执行查询,但如果处于等待状态太久会出错
【发布时间】:2014-03-13 03:45:57
【问题描述】:

有没有办法让应用程序向数据库发送查询,但如果查询等待时间过长,数据库会终止查询并抛出错误?比如:

WAIT FOR CAST('1 min' AS INTERVAL) <your query here>

如果pg_stat_activity 中的waiting 的值一直是true 的时间超过给定的时间间隔,则数据库应取消查询并返回错误,应用程序会将其解释为Exception

这样的东西存在吗?或者有没有什么变通方法(最好用Java写的)可以达到同样的效果?

我所针对的一个特定用例是这样的(在 Java 代码的简化形式中):

try {
    statement.executeUpdate("WAIT FOR CAST('30 sec' AS INTERVAL) TRUNCATE my_table");
    //TRUNCATE may wait if other processes are accessing the table,
    //example a backup process that has locked the table.
} catch (WaitTimeoutException wte) {
    statement.executeUpdate("DELETE FROM my_table");
}

这个想法是最好使用TRUNCATE,因为这样会更快,但如果查询最终等待太久,那么我应该回退到DELETE 来完成工作。

这也可用于在其他用例中使查询超时,您不希望应用程序永远等待。相反,应用程序可以检测到“等待太久”的情况并采取适当的行动(例如提醒用户或在登录后重试)。

【问题讨论】:

  • 我的印象是 Postgres 对setQueryTimeout 的支持很差,但我会试一试。
  • 在最坏的情况下,您可以设置使用操作系统的 socketTimeout,这样应该可以工作。
  • setQueryTimeout 是否会取消实际的执行查询,而该查询所用的时间超过了超时时间?虽然我希望它取消一个 waiting 查询,但我不希望它取消一个不等待但实际执行的查询。由于文档“设置驱动程序等待语句对象执行的秒数”,我非常怀疑,因为它暗示这是等待 DBMS 在超时内完成执行的驱动程序,而不是等待释放表以供访问的 DBMS。 我正在寻找的是后一种情况。
  • 您是否知道,如果一个事务以需要锁定的方式使用表,则同一个表上的另一个事务可能最终会等待第一个事务完成?我不是在谈论中途停止截断。我说的是自动取消尚未开始但正在等待另一个事务完成的截断。超时它不应该等待比这更长的时间。但是,如果没有等待,则超时根本不适用。请查看pg_stat_activity.waiting is true 的含义。

标签: java sql database postgresql postgresql-9.1


【解决方案1】:

试试:

SET lock_timeout TO 1000; OR
SET statement_timeout TO 1000;

更多信息请访问: http://www.postgresql.org/docs/current/static/runtime-config-client.html#RUNTIME-CONFIG-CLIENT-STATEMENT

【讨论】:

  • 我相信这也和其他建议有同样的问题。它将中止任何花费超过超时时间的语句无论是执行还是等待。但是lock_timeout (integer)呢?
  • 抱歉错过了这个细节。 lock_timeout 看起来它可能会做你想做的事,测试她并确定。
猜你喜欢
  • 2020-08-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-01-17
相关资源
最近更新 更多