我试图在使用 Postgres (psycopg) 连接时更好地理解“自动提交”的概念。假设我有一个新连接,将其隔离级别设置为 ISOLATION_LEVEL_AUTOCOMMIT,然后直接运行此 SQL,而不使用游标开始/回滚方法(作为练习;并不是说我真的想这样做):

INSERT A
INSERT B
BEGIN
    INSERT C
    INSERT D
ROLLBACK

INSERT C 和 D 会发生什么情况?

自动提交纯粹是 psycopg 中的一个内部设置,会影响它发出 BEGIN 的方式吗?在这种情况下,上述 SQL 不受影响;INSERT A 和 B 在完成后立即提交,而 C 和 D 在事务中运行并回滚。该事务在什么隔离级别下运行?

或者自动提交是连接本身的真实设置吗?那么,它如何影响 BEGIN 的处理呢?它是被忽略,还是覆盖自动提交设置以实际启动事务?该事务在什么隔离级别下运行?

还是我完全偏离了目标?

有帮助吗?

解决方案

自动提交模式意味着每个语句隐式地开始和结束事务。

在您的情况下,如果自动提交关闭:

  • 客户端将隐式启动第一个语句的事务
  • BEGIN 将发出警告,表示事务已开始
  • ROLLBACK 将回滚所有四个语句

当自动提交打开时,只有 cd 被回滚。

注意 PostgreSQL 没有内部 AUTOCOMMIT 自那时以来的行为 8.0:所有自动提交功能都依赖于客户端。

其他提示

缺省时,PostgreSQL已经自动提交上,这意味着每个语句作为事务处理。如果你明确告诉它开始交易,在你的榜样,这些项目是在一个新的事务。

在您的示例中,A和B将被提交,C和D将被回滚。

在自动提交是psycopg只是将一切向PostgreSQL后端没有试图来管理事务为您服务。如果你不使用BEGIN / COMMIT / ROLLBACK然后每.execute()调用立即执行和提交。您可以通过发出BEGIN / COMMIT / ROLLBACK命令,做你自己的事务管理。显然,在自动提交模式下,你不能叫conn.commit()或conn.rollback(),因为psycopg不跟踪的交易,而只是发送任何你.execute()直接到后端。

在您的示例A和B将被提交,C和d将被回滚。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top