PostgreSQL 中的事务是通过`psycopg2` per-cursor 还是 per-connection 进行的?

Fak*_*ame 11 postgresql

我正在使用psycopg2数据库 API对 PostgreSQL 9.3 进行一些工作。

我将 DB API 设置为最低隔离级别(“自动提交”模式),并直接通过 SQL 管理我自己的事务。例子:

cur = self.conn.cursor()
cur.execute("BEGIN;")
cur.execute("SELECT dbId, downloadPath, fileName, tags FROM {tableName} WHERE dlState=%s".format(tableName=self.tableName), (2, ))
ret = cur.fetchall()
cur.execute("COMMIT;")
Run Code Online (Sandbox Code Playgroud)

基本上,事务是由cur.execute("BEGIN;")仅限于该游标启动的,还是针对整个连接(self.conn.cursor())?

我正在做的一些更复杂的事情涉及多个单独的数据库操作,我在逻辑上将它们分解为函数。由于这一切都在一个将连接作为成员的类中,因此在每个函数中创建游标要方便得多。但是,我不确定事务中创建游标是如何工作的。

基本上,如果事务是按连接进行的,我可以在事务中即时创建大量游标。如果它们是每个光标,那意味着我必须到处传递光标。是哪个?

文档没有涉及这一点,尽管您可以调用这一事实connection.commit()使我相当确信事务控制是针对每个连接的。

Cra*_*ger 8

事务是每个会话,即每个连接。

PostgreSQL 不支持挂起和恢复事务,因此 psycopg2 不能使它们成为每个游标,除非它在幕后隐式地创建了新连接。

实际上,我没有发现 psycopg2 的游标特别有用。如果您不使用来自服务器的增量提取,它们可以保留结果集,但我认为它们没有其他好处。

为什么手动发出begincommit虽然,而不是使用它们的连接方法?

  • @FakeName 您不必明确地`begin`。如果没有交易打开,则会为您启动新的交易。您只需“提交”即可描述交易。所以是的,DB-API 模型*确实*支持显式事务。 (2认同)