SET TRANSACTION — 現在のトランザクションの特性を設定する
SET TRANSACTIONtransaction_mode[, ...] SET TRANSACTION SNAPSHOTsnapshot_idSET SESSION CHARACTERISTICS AS TRANSACTIONtransaction_mode[, ...] ここでtransaction_modeは以下のいずれかです。 ISOLATION LEVEL { SERIALIZABLE | REPEATABLE READ | READ COMMITTED | READ UNCOMMITTED } READ WRITE | READ ONLY [ NOT ] DEFERRABLE
SET TRANSACTIONは現在のトランザクションの特性を設定します。
これはそれより後のトランザクションには影響を及ぼしません。
SET SESSION CHARACTERISTICSは、セッションにおけるそれ以後のトランザクションのデフォルトのトランザクション特性を設定します。
個々のトランザクションについてSET TRANSACTIONによりデフォルト特性を上書きすることができます。
利用可能なトランザクション特性はトランザクションの隔離レベル、トランザクションのアクセスモード(読み書きモードもしくは読み取りのみモード)、遅延モードです。 さらに、セッションのデフォルトとしてではなく、現在のトランザクションのみに対してスナップショットを選択することができます。
トランザクションの隔離レベルは、並行して実行中の他のトランザクションが存在する場合、そのトランザクションが見ることができるデータを決定するものです。
READ COMMITTED1つひとつの文から見ることができるのは、その文が開始される前にコミットされた行のみです。 これがデフォルトです。
REPEATABLE READ現在のトランザクションにおける全ての文は、トランザクションで最初の問い合わせ文またはデータを変更する文が実行される前にコミットされた行だけを見ることができます。
SERIALIZABLE
現在のトランザクションにおける全ての文は、トランザクションで最初の問い合わせ文またはデータを変更する文が実行される前にコミットされた行だけを見ることができます。
同時実行のシリアライザブルトランザクションの中で読み取りと書き込みのパターンによって、これらのトランザクションの実行を直列に(同時に一度)行うことができない状況になる場合、その内1つのトランザクションはserialization_failureというエラーでロールバックされます。
標準SQLでは、READ UNCOMMITTEDというもう1つのレベルを定義しています。
PostgreSQLではREAD UNCOMMITTEDはREAD COMMITTEDとして扱われます。
トランザクション隔離レベルは、そのトランザクションにおける最初の問い合わせ文やデータ更新文(SELECT、INSERT、DELETE、UPDATE、FETCH、COPY)が実行された後では変更することができません。
トランザクションの隔離や同時実行制御についての詳細情報は第13章を参照してください。
トランザクションのアクセスモードは、そのトランザクションが読み書き可能か読み取りのみかを決定します。
デフォルトは読み書き可能です。
読み取りのみのトランザクションでは、以下のSQLコマンドの実行が制限されます。
書き込み対象のテーブルが一時テーブルでない場合、INSERT、UPDATE、DELETE、COPY FROMなどのSQLコマンドを実行できません。
すべてのCREATE、ALTER、DROP系のSQLコマンド、COMMENT、GRANT、REVOKE、TRUNCATEは、実行できません。
さらに、上述のコマンドが含まれるEXPLAIN ANALYZEとEXECUTEコマンドも実行できません。
この方法ではディスクへの書き込みをすべて防ぐわけではないので、読み取り専用の高レベルの概念です。
DEFERRABLEトランザクション属性は、トランザクションがSERIALIZABLEかつREAD ONLYである場合のみ効果があります。
あるトランザクションでこれら3つの属性がすべて選択されている場合、最初にスナップショットを獲得する時にブロックされる可能性があります。
その後、そのトランザクションをSERIALIZABLEトランザクションの通常のオーバーヘッドを伴わず、またシリアライズ処理の失敗を引き起こす恐れやシリアライズ処理の失敗によりキャンセルされる恐れもなく実行することができます。
これは時間がかかるレポート処理やバックアップによく適しています。
SET TRANSACTION SNAPSHOTコマンドにより、
既存のトランザクションと同じスナップショットを持つ新しいトランザクションを実行することができます。
既存のトランザクションはpg_export_snapshot関数(9.26.5参照)を使用してそのスナップショットを公開していなければなりません。
この関数はスナップショット識別子を返します。
どのスナップショットを取り込むかを指定するために、この識別子をSET TRANSACTION SNAPSHOTに渡さなければなりません。
このコマンドでは、この識別子を例えば'000003A1-1'のようにリテラル文字列として記述しなければなりません。
SET TRANSACTION SNAPSHOTはトランザクションの開始時、つまり、トランザクションの最初の問い合わせまたはデータ変更文(SELECT、INSERT、DELETE、UPDATE、FETCH、COPY)の前でのみ実行できます。
さらに、そのトランザクションを前もってSERIALIZABLEまたはREPEATABLE READ隔離レベルに設定していなければなりません。
(さもないと、READ COMMITTEDではコマンドそれぞれに対して新しいスナップショットを取りますので、このスナップショットは即座に破棄されます。)
取り込むトランザクションがSERIALIZABLE隔離レベルを使用している場合、スナップショットを公開したトランザクションもこの隔離レベルを使用しなければなりません。
また、読み取り専用ではないシリアライザブルトランザクションは、読み取り専用トランザクションから公開されたスナップショットを取り込むことができません。
SET TRANSACTIONを、その前にSTART TRANSACTIONやBEGINを発行することなく実行した場合、警告が発生しますが、それ以外は何の効果もありません。
BEGINあるいはSTART TRANSACTIONで目的のtransaction_modesを指定すれば、SET TRANSACTIONを使わずに済ませることができます。
しかしSET TRANSACTION SNAPSHOTに対応するオプションはありません。
セッションのデフォルトのトランザクションモードは、設定パラメータdefault_transaction_isolation、default_transaction_read_only、default_transaction_deferrableで設定することができます
(実際、SET SESSION CHARACTERISTICSはこれらの変数をSETで設定することと同等の冗長な記述に過ぎません。)。
したがって、トランザクションモードのデフォルトは設定ファイルやALTER DATABASEなどで設定可能です。
詳細は第19章を参照してください。
既存のトランザクションと同じスナップショットを持つトランザクションを新しく開始するためには、まず既存のトランザクションからスナップショットを公開します。 以下の例に示すように、これはスナップショット識別子を返します。
BEGIN TRANSACTION ISOLATION LEVEL REPEATABLE READ; SELECT pg_export_snapshot(); pg_export_snapshot --------------------- 00000003-0000001B-1 (1 row)
そして、新規に開始したトランザクションの先頭のSET TRANSACTION SNAPSHOTでこのスナップショット識別子を渡します。
BEGIN TRANSACTION ISOLATION LEVEL REPEATABLE READ; SET TRANSACTION SNAPSHOT '00000003-0000001B-1';
このコマンドは標準SQLで定義されています。
DEFERRABLEトランザクションモードとSET TRANSACTION SNAPSHOT構文は例外であり、PostgreSQLの拡張です。
標準SQLではデフォルトのトランザクションはSERIALIZABLEです。
PostgreSQLでは、通常、READ COMMITTEDがデフォルトですが、これは上述の通り変更可能です。
標準SQLでは、もう1つ、診断領域の大きさというトランザクション特性があり、このコマンドで設定可能です。 この概念は組み込みSQL固有のものなので、PostgreSQLサーバには実装されていません。
標準SQLでは、連続するtransaction_modesの間にはカンマが必要です。
歴史的な理由よりPostgreSQLではカンマを省略することができます。