On this page
43.8. TransactionManagement
在CALL
命令调用的过程以及匿名代码块(DO
命令)中,可以使用COMMIT
和ROLLBACK
命令结束事务。使用这些命令结束事务后,新事务将自动启动,因此没有单独的START TRANSACTION
命令。 (请注意,BEGIN
和END
在 PL/pgSQL 中具有不同的含义.)
这是一个简单的示例:
CREATE PROCEDURE transaction_test1()
LANGUAGE plpgsql
AS $$
BEGIN
FOR i IN 0..9 LOOP
INSERT INTO test1 (a) VALUES (i);
IF i % 2 = 0 THEN
COMMIT;
ELSE
ROLLBACK;
END IF;
END LOOP;
END
$$;
CALL transaction_test1();
事务控制只能在顶层的CALL
或DO
调用中或嵌套的CALL
或DO
调用中进行,而无需任何其他干预命令。例如,如果调用堆栈是CALL proc1()
→CALL proc2()
→CALL proc3()
,则第二和第三过程可以执行事务控制动作。但是,如果调用堆栈是CALL proc1()
→SELECT func2()
→CALL proc3()
,那么最后一个过程将无法执行事务控制,因为它们之间是SELECT
。
特殊注意事项适用于游标循环。考虑以下示例:
CREATE PROCEDURE transaction_test2()
LANGUAGE plpgsql
AS $$
DECLARE
r RECORD;
BEGIN
FOR r IN SELECT * FROM test2 ORDER BY x LOOP
INSERT INTO test1 (a) VALUES (r.x);
COMMIT;
END LOOP;
END;
$$;
CALL transaction_test2();
通常,在事务提交时,游标会自动关闭。但是,作为此类循环一部分创建的游标会被第一个COMMIT
或ROLLBACK
自动转换为可保留的游标。这意味着将在第一个COMMIT
或ROLLBACK
处对游标进行完全评估,而不是逐行进行评估。循环后,游标仍会自动删除,因此用户几乎看不见该游标。
在非只读命令(例如UPDATE ... RETURNING
)驱动的游标循环中,不允许使用事务命令。
事务不能在带有异常处理程序的块内结束。