事务管理

本文介绍了事务管理的相关内容。

简介

在由CALL命令调用的过程中以及匿名代码块(DO命令)中,可以用命令COMMITROLLBACK结束事务。在一个事务被使用这些命令结束后,一个新的事务会被自动开始,因此没有单独的START TRANSACTION命令(注意BEGINEND在 PL/SQL 中有不同的含义)。

这里是一个简单的例子:

    CREATE PROCEDURE transaction_test1()
    IS
    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();

新事务开始时具有默认事务特征,如事务隔离级别。在循环中提交事务的情况下,可能需要以与前一个事务相同的特征来自动启动新事务。 命令COMMIT AND CHAINROLLBACK AND CHAIN可以完成此操作。

只有在从顶层调用的CALLDO中才能进行事务控制,在没有任何其他中间命令的嵌套CALLDO调用中也能进行事务控制。例如,如果调用栈是CALL proc1()CALL proc2()CALL proc3(),那么第二个和第三个过程可以执行事务控制动作。但是如果调用栈是CALL proc1()SELECT func2()CALL proc3(),则最后一个过程不能做事务控制,因为中间有SELECT

对于游标循环有特殊的考虑。看看这个例子:

    CREATE PROCEDURE transaction_test2()
    IS
    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();

通常,游标会在事务提交时被自动关闭。但是,一个作为循环的组成部分创建的游标会自动被第一个COMMITROLLBACK转变成一个可保持游标。这意味着该游标在第一个COMMITROLLBACK处会被完全计算出来,而不是逐行被计算。该游标在循环后仍会被自动删除,因此这通常对用户是不可见的。

有非只读命令(UPDATE ... RETURNING)驱动的游标循环中不允许有事务命令。

事务在一个具有异常处理部分的块中不能被结束。