使用psycopg2

时间:2015-08-01 18:00:56

标签: python postgresql psycopg

我正在访问带有序列化事务隔离的postgresql表。我正在做这样的事情(现有的psycopg2连接conn和该连接中的游标cur

while True:
  try:
    cur.execute(query)
    break
  except TransactionRollbackError:
    [sleep a little]
    continue
  except Exception:
    [handle error here]

这一点是在序列化争用的情况下重试。现在,这在很多时候都很好用。但是,经常在TransactionRollbackError陷阱中进行一次迭代后,我会收到此错误:

current transaction is aborted, commands ignored until end of transaction block。显然,以这种方式旋转以避免序列化争用是不合适的?我应该以不同的方式做这件事吗?

一些注意事项:我正在使用不同的进程访问表(这些进程完全相同并执行相同的操作:选择,递增和更新/插入表中。)每个进程都有自己的连接{{1他们没有共享连接。

另一个注意事项:似乎在经过conn异常块之后,在while循环的下一次旋转中,它最终会在TransactionRollbackError异常块中结束。

还有一点需要注意:同时运行的进程数直接影响错误的频率,因为更多进程往往会产生更多错误。所以有一些争论正在进行中。我的印象是使用带有重试的序列化事务隔离(如我的演示代码中)将解决此问题。

1 个答案:

答案 0 :(得分:4)

您应该在except TransactionError:分支中执行rollback以从错误状态中恢复:

while True:
  try:
    cur.execute(query)
    break
  except TransactionRollbackError:
    conn.rollback()
    [sleep a little]
    continue
  except Exception:
    [handle error here]

这是recommendation made the FAQ as well

请注意,除非您一直在进行自己的事务控制或以autocommit模式建立连接,否则它将回滚所有 SQL命令。