# 43.8.交易管理

呼叫命令以及匿名代码块中(命令),可以使用命令结束事务犯罪回降。在使用这些命令结束事务后,新事务会自动启动,因此没有单独的开始交易命令(注意开始终止在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();

新事务从默认事务特征开始,例如事务隔离级别。在循环中提交事务的情况下,可能需要自动启动具有与前一个相同特征的新事务。命令承诺和约束回滚和链做到这一点。

事务控制只能在呼叫从顶层调用或嵌套调用呼叫无需任何其他干预命令的调用。例如,如果调用堆栈调用proc1()调用proc2()调用proc3(),则第二和第三个过程可以执行事务控制操作。但是如果调用堆栈调用proc1()选择func2()调用proc3(),则最后一个过程无法进行事务控制,因为选择介于两者之间。

特殊注意事项适用于光标循环。考虑这个例子:

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();

通常,游标在事务提交时自动关闭。但是,作为这样的循环的一部分创建的光标会被第一个循环自动转换为可保持的光标犯罪回降.这意味着光标在第一次被完全评估犯罪回降而不是一排一排。循环结束后,光标仍会自动移除,因此用户基本上看不到光标。

在由非只读命令驱动的游标循环中不允许使用事务命令(例如使现代化返回).

事务不能在具有异常处理程序的块内结束。