バージョンごとのドキュメント一覧

41.8. トランザクション制御 #

<title>Transaction Management</title>

In procedures invoked by the <command>CALL</command> command as well as in anonymous code blocks (<command>DO</command> command), it is possible to end transactions using the commands <command>COMMIT</command> and <command>ROLLBACK</command>. A new transaction is started automatically after a transaction is ended using these commands, so there is no separate <command>START TRANSACTION</command> command. (Note that <command>BEGIN</command> and <command>END</command> have different meanings in PL/pgSQL.) CALLコマンドで呼び出されたプロシージャ、また同様に無名コードブロック(DOコマンド)では、COMMITおよびROLLBACKコマンドを使ってトランザクションを終えることができます。 トランザクションをこれらコマンドで終了した後、新たなトランザクションが自動的に開始されます。そのため、別途のSTART TRANSACTIONはありません。 (PL/pgSQLではBEGINENDは別の意味を持つことに注意してください。)

Here is a simple example: 以下に例を示します。

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

A new transaction starts out with default transaction characteristics such as transaction isolation level. In cases where transactions are committed in a loop, it might be desirable to start new transactions automatically with the same characteristics as the previous one. The commands <command>COMMIT AND CHAIN</command> and <command>ROLLBACK AND CHAIN</command> accomplish this. 新しいトランザクションは、トランザクション分離レベル等のデフォルトのトランザクションの特性で開始します。 トランザクションがループ内でコミットされた場合、新しいトランザクションは前のトランザクションと同じ特性で自動的に開始するのが好ましいかもしれません。 コマンドCOMMIT AND CHAINROLLBACK AND CHAINはそのように動作します。

Transaction control is only possible in <command>CALL</command> or <command>DO</command> invocations from the top level or nested <command>CALL</command> or <command>DO</command> invocations without any other intervening command. For example, if the call stack is <command>CALL proc1()</command> &rarr; <command>CALL proc2()</command> &rarr; <command>CALL proc3()</command>, then the second and third procedures can perform transaction control actions. But if the call stack is <command>CALL proc1()</command> &rarr; <command>SELECT func2()</command> &rarr; <command>CALL proc3()</command>, then the last procedure cannot do transaction control, because of the <command>SELECT</command> in between. トランザクション制御は、トップレベル、または、他の干渉するコマンドを伴わない入れ子のCALLまたはDO呼び出しからの、CALLまたはDOによる呼び出しのみで可能です。 例えば、呼び出しスタックがCALL proc1()CALL proc2()CALL proc3()である場合、二番目と三番目のプロシージャはトランザクション制御を実行できます。 しかし、呼び出しスタックがCALL proc1()SELECT func2()CALL proc3()である場合、間のSELECTのため、最後のプロシージャはトランザクション制御を実行できません。

<application>PL/pgSQL</application> does not support savepoints (<command>SAVEPOINT</command>/<command>ROLLBACK TO SAVEPOINT</command>/<command>RELEASE SAVEPOINT</command> commands). Typical usage patterns for savepoints can be replaced by blocks with exception handlers (see <xref linkend="plpgsql-error-trapping"/>). Under the hood, a block with exception handlers forms a subtransaction, which means that transactions cannot be ended inside such a block. 《機械翻訳》PL/pgSQLはセーブポイントをサポートしません(SAVEPOINT/ROLLBACK TO SAVEPOINT/RELEASE SAVEPOINT)。 セーブポイントの典型的な使用パターンは、例外ハンドラを持つブロックに置き換えることができます(41.6.8を参照)。 内部では、例外ハンドラを持つブロックがサブトランザクションを形成します。 これは、そのようなブロック内ではトランザクションを終了できないことを意味します。

Special considerations apply to cursor loops. Consider this example: カーソルループには特別な考慮事項が当てはまります。 以下の例をよく確認してください。

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

Normally, cursors are automatically closed at transaction commit. However, a cursor created as part of a loop like this is automatically converted to a holdable cursor by the first <command>COMMIT</command> or <command>ROLLBACK</command>. That means that the cursor is fully evaluated at the first <command>COMMIT</command> or <command>ROLLBACK</command> rather than row by row. The cursor is still removed automatically after the loop, so this is mostly invisible to the user. But one must keep in mind that any table or row locks taken by the cursor's query will no longer be held after the first <command>COMMIT</command> or <command>ROLLBACK</command>. 《マッチ度[68.597561]》通常、カーソルはトランザクションのコミット時に自動的に閉じられます。 しかしながら、このようにループの一部として作られたカーソルは、最初のCOMMITまたはROLLBACKから自動的にホールドカーソルに変換されます。 このことは、今や、最初のCOMMITROLLBACKの時点でカーソルが行ごとではなく完全に評価されることを意味します。 従来通りカーソルはループ後に自動で削除されるので、このことはユーザにほとんど認識されません。 《機械翻訳》通常、カーソルはトランザクションコミットで自動的に閉じたになります。 ただし、このようなループのパートとして作成されたカーソルは、最初のCOMMITまたはROLLBACKによって自動的に保持可能なカーソルに変換されます。 これは、カーソルが行によって行ではなく、最初のCOMMITまたはROLLBACKで完全に評価されることを意味します。 カーソルはループの後に自動的に除去されるため、これはユーザにはほとんど見えません。 しかし、カーソルのクエリによって取られたテーブルまたは行の鍵は、最初のCOMMITまたはROLLBACKの後にはもはや保持されないことに留意しなければならない。

Transaction commands are not allowed in cursor loops driven by commands that are not read-only (for example <command>UPDATE ... RETURNING</command>). トランザクションコマンドは、読み込み専用でないコマンド(例えばUPDATE ... RETURNING)で駆動されるカーソルループ内では許可されません。