23

有没有办法在psycopg2中为数据库事务或数据库查询设置超时?

一个示例用例:
Heroku 将 django Web 请求限制为 30 秒,之后 Heroku 终止请求,不允许 django 优雅地回滚任何尚未返回的事务。这可能会使未完成的事务在 postgres 上处于打开状态。您可以在数据库中配置超时,但这也会限制与 Web 无关的查询,例如维护脚本分析等。在这种情况下,最好通过中间件(或通过 django)设置超时。

4

3 回答 3

43

您可以使用 options 参数在连接时设置超时。语法有点奇怪:

>>> import psycopg2
>>> cnn = psycopg2.connect("dbname=test options='-c statement_timeout=1000'")
>>> cur = cnn.cursor()
>>> cur.execute("select pg_sleep(2000)")
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
psycopg2.extensions.QueryCanceledError: canceling statement due to statement timeout

也可以使用 env 变量进行设置:

>>> import os
>>> os.environ['PGOPTIONS'] = '-c statement_timeout=1000'
>>> import psycopg2
>>> cnn = psycopg2.connect("dbname=test")
>>> cur = cnn.cursor()
>>> cur.execute("select pg_sleep(2000)")
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
psycopg2.extensions.QueryCanceledError: canceling statement due to statement timeout
于 2013-12-17T12:38:04.877 回答
12

您可以随时使用 SQL 设置每个语句的超时。例如:

SET statement_timeout = '2s'

将中止任何花费超过 2 秒的语句(跟随它)(您可以使用任何有效的单位作为 's' 或 'ms')。请注意,当语句超时时,psycopg 会引发异常,您需要注意捕捉它并采取适当的行动。

于 2013-11-20T16:26:03.563 回答
1

看起来 PostgreSQL 9.6 添加了空闲事务超时。看:

Heroku 也支持 PostgreSQL 9.6,所以你应该可以使用它。

于 2017-08-11T05:46:24.540 回答