うまくいけば簡単な質問ですが、まともな回答はすぐに見つかりませんでした。 PostgreSQL(特にバージョン9.0.4)のストアドプロシージャ(ユーザ定義のDB関数)は、それ自体がトランザクションであるSELECT文を介して呼び出されるため、本質的にトランザクショナルです。だから、どのようにストアドプロシージャの分離レベルを選択するのですか?他のDBMSでは、望ましいトランザクション・ブロックが、START TRANSACTIONブロックにラップされると考えられます。このブロックでは、望ましい分離レベルがオプションのパラメータです。postgresqlストアドプロシージャの隔離レベルを設定します
CREATE FUNCTION add_new_row(rowtext TEXT)
RETURNS VOID AS
$$
BEGIN
INSERT INTO data_table VALUES (rowtext);
UPDATE row_counts_table SET count=count+1;
END;
$$
LANGUAGE plpgsql
SECURITY DEFINER;
と私は確信してこの関数は常にシリアライザブルトランザクション(はい、はい、PostgreSQLのSERIALIZABLE ISNのように行われるようにしたいと想像:特定作らアップの例として、私はこれをしたい
を言います適切なシリアライズ可能ですが、それはポイントではありません)。
START TRANSACTION ISOLATION LEVEL SERIALIZABLE;
SELECT add_new_row('foo');
COMMIT;
したがって、必要な分離レベルを関数にプッシュするにはどうすればよいですか?同じ名前の SQLとPL/pgSQLで文 をまとめるためのBEGIN/ENDの使用 を混同しないことが重要であるthe manual says
ように私は、私はちょうど
BEGIN
文の分離レベルを置くことができないと信じてトランザクション制御のコマンド。 PL/pgSQLのBEGIN/ENDは、グループ化が の場合のみです。 トランザクションを開始または終了しません。関数と 手順をトリガーは常に 内、外 クエリによって確立されたトランザクションを実行している - 。彼らはそのトランザクションを開始したり、 コミットすることはできません、彼らがで実行するための 何の関連もないので、
最も明白なこれは受け入れられるだろうが、私へのアプローチは、私が仕事にこれに頼ることができるよりも、それは明らかではない、関数定義のSET TRANSACTION
どこか、例えば,:
CREATE FUNCTION add_new_row(rowtext TEXT)
RETURNS VOID AS
$$
BEGIN
SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;
INSERT INTO data_table VALUES (rowtext);
UPDATE row_counts_table SET count=count+1;
END;
$$
LANGUAGE plpgsql
SECURITY DEFINER;
を使用することです。 SET TRANSACTION
ためdocumentationは、SET TRANSACTIONが せずに前のSTART TRANSACTIONを実行またはBEGINされた場合、 が トランザクションはすぐに終了するので、効果がないように見えます
言います。 (Iが無効に自動コミットを持っていない提供)私は孤独
SELECT add_new_row('foo');
文を呼び出す場合、私は期待しているので、困惑私の葉
SELECTは、セッションのデフォルトの分離レベルでシングルライントランザクションとして実行することができます。
manualも書かれています:
トランザクション分離レベルが が最初の問い合わせや データ変更ステートメントの後に変更することはできません(FETCH、UPDATE、DELETE、 INSERTを選択するか、 COPY)のトランザクションは が実行されました。。関数は、下の分離レベルでトランザクション内から呼び出された場合例えば
は、だから何が起こる:ボーナスの質問については
START TRANSACTION ISOLATION LEVEL READ COMMITTED;
UPDATE row_counts_table SET count=0;
SELECT add_new_row('foo');
COMMIT;
:関数の言語は任意の違いを作るのですか? PL/pgSQLでプレーンSQLとは違った分離レベルを設定するでしょうか?
私はスタンダードとベストプラクティスを文書化しているので、まともな参考文献があれば幸いです。
関数内で 'SET TRANSACTION'を使用しようとしたときにはどうでしたか? –
@a_horse_with_no_name:私が言及したように、私は 'SET TRANSACTION'が私の必要とするものであり、その機能は受け入れられますが、時にはそれほど多くのことを意味するものではありません(時にはいくつかのオプションが時々飲み込まれる)ので、ちょうどうまくいくようなものではなく、文書化されたアプローチです。 – beldaz
Postgresはあなたの言うことをまったく飲み込むことはほとんどありません。 –