【问题标题】:JDBC postgres query with a timeoutJDBC postgres 查询超时
【发布时间】:2009-07-24 00:07:54
【问题描述】:

不幸的是,JDBC/postgres 没有实现 setTimeout。有什么方法可以模拟或解决这个问题吗?从功能上讲,我想执行查询,如果需要的时间超过 N 秒则中断

【问题讨论】:

  • 我发现这个问题和答案对我遇到的 python/psycopg2 问题也很有帮助。 Psycopg2 似乎在连接时允许超时设置,但在我的情况下,这个接口被抽象掉了。添加此评论以使其他搜索 SO 的人受益。

标签: postgresql jdbc


【解决方案1】:

"statement_timeout" 看起来像你想要的。

SET statement_timeout TO 1000; -- for a second
<your_query_here>;
RESET statement_timeout; -- reset

【讨论】:

  • 你最好使用 RESET statement_timeout;查询完成后 - 如果有默认值...
  • 在 pgAdmin3 上测试过这个。仅当 SET statement_timeout 与实际查询分开执行时才有效。当一起执行时,pgAdmin3 使用已经设置的任何超时值,并且不使用查询提供的值。
  • 或者,使用 SET LOCAL statement_timeout TO 1000,它将范围限制为当前事务。这样您就不必担心是否会进入 RESET,您只需要限制事务的范围即可。
  • 为了更清楚,我只是写了自己的答案;随时更新您的。
【解决方案2】:

一种方法可能是尝试在 Timer 类中运行查询。如果 Timer 结束但没有返回值,则抛出异常。

HibernateJDO 提供了这样的结构。也许它们对你来说是不错的选择。

【讨论】:

  • 你必须小心这是如何实现的;如果做错了,你最终会得到许多阻塞的线程,这些线程持有被忽略的 SQL 连接。这里的部分问题是,如果线程正在做某事,您不能强制线程抛出异常。
【解决方案3】:

使用 LOCAL 关键字将statement_timeout 的范围限制为当前事务。这样,如果出现任何问题(例如超时),超时就会重置。

BEGIN TRANSACTION;
SET LOCAL statement_timeout TO 1000;    -- one-second timeout
SELECT COUNT(*) FROM really_huge_table; -- your slow query
ROLLBACK;                               -- reset

【讨论】:

    【解决方案4】:

    如果您使用 c3p0 作为数据源会怎样?它有很多可配置的选项,对于古怪的数据库和网络,例如,acquireRetryAttempts、acquireRetryDelay 和 breakAfterAcquireFailure。

    【讨论】:

    • FWIW 在 c3p0 文档中没有“连接超时”之类的东西:mchange.com/projects/c3p0 - 只提到与这里的问题完全无关的“checkoutTimeout”:checkoutTimeout 限制客户端的时间长度如果所有连接都已签出并且无法立即提供一个连接,则将等待连接。
    猜你喜欢
    • 2010-11-19
    • 2018-08-03
    • 2019-02-26
    • 2016-01-15
    • 1970-01-01
    • 1970-01-01
    • 2012-01-05
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多