如何防止psycopg2锁定表

Mik*_*e T 8 python postgresql psycopg2 database-deadlocks postgresql-9.1

我在PostgreSQL 9.1服务器上有一个表,如下所示:

CREATE TABLE foo(id integer PRIMARY KEY);
Run Code Online (Sandbox Code Playgroud)

在一个带psycopg2(≥2.4.2)的交互式Python shell中,我可能会启动一个连接和游标,并查询该表:

import psycopg2
conn = psycopg2.connect('dbname=...')
curs = conn.cursor()
curs.execute('SELECT * FROM foo;')
curs.fetchall()
Run Code Online (Sandbox Code Playgroud)

但是,如果我然后尝试修改表:

ALTER TABLE foo ADD COLUMN bar integer;
Run Code Online (Sandbox Code Playgroud)

这会引发虚拟死锁,直到我conn.close()从Python开始.

如何启动与psycopg2的简单连接,以防止它在其他地方创建由DDL更改引起的死锁?Python中的连接可以是只读的.

Mik*_*e T 10

我找到的解决方案是使用set_session,如下所示:

conn.set_session(readonly=True, autocommit=True)
Run Code Online (Sandbox Code Playgroud)

autocommit警告文件:

默认情况下,任何查询执行,包括一个简单的SELECT都将启动一个事务:对于长时间运行的程序,如果不采取进一步的操作,会话将保持"在事务中空闲",这是一个不合适的条件,原因有几个(锁定由会议,表膨胀......).对于长期存在的脚本,要么确保尽快终止事务,要么使用自动提交连接.

这总结了问题中简单SELECT的经验.

  • 您也可以只执行 `conn.commit()` 而不是将 `autocommit` 设置为 `True` (2认同)