11

MS SQLの世界から来た私は、ストアドプロシージャを多用する傾向があります。私は現在、多くのPostgreSQLplpgsql関数を使用するアプリケーションを作成しています。私がやりたいのは、特定の関数内のいずれかの時点で例外が発生した場合に、特定の関数内に含まれるすべてのINSERTS/UPDATESをロールバックすることです。

私は当初、各関数が独自のトランザクションにラップされており、例外によってすべてが自動的にロールバックされるという印象を受けました。しかし、そうではないようです。代わりに、例外処理と組み合わせてセーブポイントを使用する必要があるかどうか疑問に思っていますか?しかし、これが最善のアプローチであるかどうかを知るために、トランザクションとセーブポイントの違いを本当に理解していません。何かアドバイスはありますか?

CREATE OR REPLACE FUNCTION do_something(
         _an_input_var int
                ) RETURNS bool AS $$
        DECLARE
                _a_variable int;
        BEGIN
                INSERT INTO tableA (col1, col2, col3)
                        VALUES (0, 1, 2);

                INSERT INTO tableB (col1, col2, col3)
                        VALUES (0, 1, 'whoops! not an integer');

                -- The exception will cause the function to bomb, but the values 
                -- inserted into "tableA" are not rolled back.    

                RETURN True;
END; $$ LANGUAGE plpgsql;
4

4 に答える 4

17

関数トランザクションを表します。BEGIN/COMMITで関数をラップする必要はありません。

于 2010-03-11T17:45:15.710 に答える
4

関数でcommitまたはrollbackコマンドを使用することはできませんが、コミットされたトランザクションで関数を使用することはできます。

トランザクションの開始; SELECT do_something(); 専念;

このSQLスクリプトは、do_somethingに例外がない場合にのみコミットし、その後、関数のトランザクションをロールバックします。

于 2012-03-14T01:54:03.923 に答える
1

ドキュメントはこれを言います:

セーブポイントは、トランザクション内の特別なマークであり、確立後に実行されたすべてのコマンドをロールバックして、トランザクションの状態をセーブポイントの時点の状態に復元できます。

彼らも例を挙げています。

編集:

トランザクションをBEGINコマンドとCOMMITコマンドでラップする必要があります。

トランザクションは、トランザクションのSQLコマンドをBEGINコマンドとCOMMITコマンドで囲むことによって設定されます。

于 2010-03-11T03:01:42.410 に答える
1

セーブポイントは、ネストされたトランザクションをエミュレートするために使用できます。postgresqlトランザクションは、適用または破棄される一連のステートメントであるため、セーブポイントは、ロールバックを可能にするそのシーケンス内のポイントをマークできます。

真のネストされたトランザクションはサポートされていないため、これが最善の策です(そしてそれが適切です)。

于 2010-03-11T03:03:35.893 に答える