トランザクションを開始し、その特性を指定します。トランザクションとは、その変更を永続化できる、または1つの単位としてのみ元に戻せる文の集合です。トランザクションは、COMMIT文またはROLLBACK文で終了します。COMMIT文でトランザクションを終了する場合、文によるデータベースへのすべての変更は永続化されます。ROLLBACK文でトランザクションを終了する場合、文は有効になりません。
別のトランザクションを開始または宣言する前に、トランザクションをCOMMIT文またはROLLBACK文で終了する必要があります。別のトランザクションがアクティブな状態でトランザクションを開始または宣言しようとすると、エラー・メッセージが生成されます。
SET TRANSACTION文以外にも、他の2つの方法のいずれかでトランザクション特性を指定できます。
- DECLARE TRANSACTION文を指定した場合、文の宣言が有効になるのは、SET TRANSACTION文によって開始されていない新規トランザクションが開始されるときです。SQLでは、DECLARE TRANSACTION文、COMMIT文またはROLLBACK文に続く最初の実行可能データ操作文またはデータ定義文で新規トランザクションが開始されます。
- DECLARE TRANSACTION文およびSET TRANSACTION文の両方を省略した場合、COMMIT文またはROLLBACK文に続く最初の実行可能データ操作文またはデータ定義文で(読取り/書込みオプションを使用して)自動的にトランザクションが開始されます。このため、明示的にトランザクションを宣言または設定せずに、データを取得および更新できます。
SET TRANSACTION文のかわりにDECLARE TRANSACTION文を使用するタイミングの例は、「使用方法」を参照してください。
SET TRANSACTION文で、次のような多数のオプションを指定できます。
- トランザクション・モード(READ ONLY/READ WRITE)
- ロック指定句(RESERVINGオプション)
- 水平パーティション指定(RESERVINGオプション)
- 待機モード(WAIT/NOWAIT)
- 分離レベル
- 制約評価の指定句
- トランザクションに関与する各データベースのすべての先行オプションの複数セット(ON ... AND ON)
これらのオプションの詳細は、「引数」の項で説明します。
SET TRANSACTION文は次の環境で使用できます。
- 対話型SQL内
- プリコンパイル対象のホスト言語プログラムに埋め込まれる場合
- SQLモジュールのプロシージャの一部として
- 動的SQLで動的に実行される文として
alias
制約の別名を指定します。マルチスキーマ・データベースの別名の使用の詳細は、「使用方法」を参照してください。BATCH UPDATE
大量のロード操作のオーバーヘッドを削減するためのバッチ更新モードを指定します。更新操作の速度を上げるため、Oracle Rdbのバッチ更新トランザクションでは、スナップショット・ファイルまたはリカバリ・ユニット・ジャーナル・ファイルへの書込みが行われません。バッチ更新トランザクションの詳細は、『Oracle Rdb7 Guide to SQL Programming』を参照してください。バッチ更新トランザクションでは、リカバリ・ユニット・ジャーナル(.ruj)・ファイルを作成せずにデータベースを更新できます。したがって、トランザクション中に変更された行または索引はロールバックできません。これは、Oracle Rdbでは変更されたレコードの変更前のイメージが保持されないためです。
たとえば、開発目的のために大規模なテスト・データベースが必要な場合、バッチ更新トランザクションでは、データベースはロードされますが、ジャーナリング機能は無視されます。ロードが失敗した場合、データベースを再作成する必要があります。
分散トランザクションではバッチ更新トランザクションを使用できないため、バッチ更新トランザクションを開始する前にSQL$DISABLE_CONTEXT論理名をTRUEに定義する必要があります。(分散トランザクションでは、トランザクションがロールバック可能であることが必要です。)
データベースに対して開始されたバッチ更新トランザクションには、追加引数を含めることはできません。ただし、同じトランザクション宣言で参照される他のデータベースには、他の引数を含めることができます。
たとえば、次の文は有効です。
SQL> SET TRANSACTION ON OLD_DB USING (READ ONLY) cont> AND ON NEW_DB USING (BATCH UPDATE);
注意
プログラムでバッチ更新トランザクションを開始する前に、RMU Backupコマンドを使用してデータベースのバックアップ・コピーを作成する必要があります。通常はトランザクションのロールバックで終了するプログラムでエラーが発生した場合、Oracle Rdbではデータベースは破損しているとマークされます。破損したデータベースからリカバリするには、データベースのバックアップ・コピーからデータベースを再作成する必要があります。エラー状況を修正した後、プログラムを最初から再開できます。バッチ更新トランザクションが完了した後も、データベースをバックアップする必要があります。
constraint-name
制約の名前を指定します。db-txns
別のトランザクション・オプションを指定します。複数のデータベースにアタッチするときにデータベースごとに異なるトランザクション・オプションを指定する場合、この句を使用します。evaluating-clause
指定した制約が評価される時点を指定します。VERB TIMEを指定すると、制約はデータ操作文の発行時に評価されます。COMMIT TIMEを指定すると、制約はSET ALL CONSTRAINTS文の設定に基づいて評価されます。読取り専用トランザクションの場合、この句は使用できますが、無視されます。FOR EXCLUSIVE
FOR PROTECTED
FOR SHARED
SQL共有モードを指定します。選択するキーワードにより、予約している表で他のユーザーに実行を許可する操作が決まります。読取り専用トランザクションの宣言時にEXCLUSIVE共有モードまたはPROTECTED共有モードを指定できますが、これらのエントリは無視され、SHAREDモードが指定されます。デフォルトはSHAREDです。表6-17は、各種共有モードを示しています。
表6-17 SQL共有モード オプション アクセス制約 SHARED
(デフォルト)他のユーザーも同じ表を使用できる。これらのユーザーには、選択するオプションに応じて、表に対する読取り専用アクセス権または読取り/書込みアクセス権が付与される。 PROTECTED 使用している表を他のユーザーが読み取ることができる。これらのユーザーには書込みアクセス権はない。 EXCLUSIVE 他のユーザーは、トランザクションに含まれる表からレコードを読み取ることはできない。他のユーザーがDECLARE TRANSACTION文内の同じ表を参照すると、そのユーザーのアクセスは拒否される。 状況によっては、ベース・データベース・システムにより、問合せの処理時に共有予約が保護または排他に昇格される場合がある。
表6-18は、様々なロック指定の影響の比較を示しています。
表6-18 更新に関する行ロックの比較 ロック指定 SHARED WRITE PROTECTED WRITE EXCLUSIVE WRITE BATCH UPDATE .rujへの書込み ○ ○ ○ × .snpへの書込み ○ ○ × × リカバリ ○ ○ ○ × マルチユーザー・アクセス ○ ○ × ×
ISOLATION LEVEL READ COMMITTED
ISOLATION LEVEL REPEATABLE READ
ISOLATION LEVEL SERIALIZABLE
SQLトランザクションでのデータベース操作が、同時実行トランザクションでのデータベース操作による影響を受ける程度を定義します。これにより、データベースでデータの整合性が保護される程度が決まります。Oracle Rdbでは、分離レベルとしてREAD COMMITTED、REPEATABLE READおよびSERIALIZABLEをサポートしています。Oracle RdbデータベースでSQLを使用する場合、デフォルトでは、トランザクションは分離レベルSERIALIZABLEで実行されます。分離レベルが高くなるほど、トランザクションが現在実行中の他のトランザクションから分離される程度が高くなります。分離レベルにより、同時トランザクションの実行時に発生が許容される現象のタイプが決まります。トランザクションのSQL分離レベルは、次の2つの現象によって定義されます。
- ノンリピータブル・リード
1つのトランザクション内でSQL操作によって表内の同じ行が2回読み取られるときに異なる結果が返されるのを許可します。ノンリピータブル・リードが発生するのは、トランザクション読取りの間に別のトランザクションによって行が変更され、この変更がコミットされる場合です。- ファントム
1つのトランザクション内でSQL操作によってデータ値の範囲取得(または同等データの存在チェック)が2回行われるときに異なる結果が返されるのを許可します。ファントムが発生するのは、範囲取得の実行の間に別のトランザクションによって新規レコードが挿入され、この挿入がコミットされる場合です。
許可される現象は、分離レベルごとに異なります。表6-19は、SET TRANSACTION文で明示的に指定可能な分離レベルで許可される現象を示しています。
表6-19 各分離レベルで許可される現象 分離レベル ノンリピータブル・リード
の許可ファントム
の許可READ COMMITTED ○ ○ REPEATABLE READ × ○ SERIALIZABLE × ×
常に分離レベルSERIALIZABLEで実行される読取り専用トランザクションの場合、スナップショットを有効にすると、COMMIT文を発行する前の別のユーザーによる変更が表示されないことがデータベース・システムによって保証されます。
トランザクションにおける分離レベルの指定の詳細は、『Oracle Rdb7 Guide to SQL Programming』を参照してください。
NAME transaction-name
トランザクションのタイトルを指定します。この情報は、SET FLAGS TRANSACTIONキーワードによって表示されます。
SQL> declare transaction read write name 'default-transaction'; SQL> select * from rdb$database; ~T Compile transaction (3) on db: 1 ~T Transaction Parameter Block: (len=23) 0000 (00000) TPB$K_VERSION = 1 0001 (00001) TPB$K_BUFFER_NAME "default-transaction" 0016 (00022) TPB$K_WRITE (read write) ~T Start_transaction (3) on db: 1, db count=1 . . .
ON alias
AND ON alias
トランザクション・オプションを指定するデータベースの別名を指定します。別名とは、データベースの特定のアタッチに付ける名前です。マルチスキーマ・データベースの別名の使用の詳細は、「使用方法」を参照してください。複数のデータベースにアタッチするときにデータベースごとに異なるトランザクション・オプションを指定する場合、ON句を使用します。(ON句を省略すると、アタッチされているすべてのデータベースにSET TRANSACTION文の1セットのトランザクション・オプションが適用されます。)
複数のON句をANDキーワードで区切ることにより、複数セットのトランザクション・オプションをデータベースごとに1つずつ含めることができます。複数データベース・トランザクションの例は、例3を参照してください。
PARTITION (part-num)
PARTITIONをRESERVING句と使用することにより、表のパーティションのサブセットのみが予約されるよう数値パーティション番号のリストを指定します。たとえば、アプリケーションは複数の処理ジョブを発行し、各ジョブによってEXCLUSIVEアクセス用として表のパーティションが個別に予約されるようにできます。この句を省略すると、デフォルトでは、すべてのパーティションが予約されます。アプリケーションがパーティションを参照したときに表が予約されていない場合、エラーがレポートされます。part-num
パーティションの数値識別子です。パーティションには1から順に番号が付けられます。CREATE INDEX文では、これらの値が割り当てられ、RDB$STORAGE_MAP_AREAS表のRDB$ORDINAL_POSITION列に記録されます。READ
WRITE
DATA DEFINITION
ロック・タイプを指定します。これらのキーワードにより、予約している表に対する操作内容を宣言します。READは、表からデータの読取りのみを行う場合に使用します。読取り専用トランザクションの場合、これがデフォルトです。
WRITEは、表のデータを挿入、更新または削除する場合に使用します。読取り/書込みトランザクションの場合、これがデフォルトです。読取り専用トランザクションにはWRITEを指定できません。
DATA DEFINITIONは、他のユーザーと同時に同じ表でメタデータを作成または変更する場合に使用します。この句は、読取り/書込みトランザクションでのみ使用できます。詳細は、「使用方法」を参照してください。
READ ONLY
読取り専用トランザクションの開始時にデータベースのスナップショットを取得します。使用している表の行は他のユーザーによる更新が可能ですが、トランザクションで取得される行は、トランザクションの開始時に存在していた行です。読取り専用トランザクションで、行を更新、挿入または削除したり、データ定義文を実行できません。ただし、ローカル一時表の宣言や、作成または宣言された一時表でのデータの変更は例外です。読取り専用トランザクションは、暗黙的に分離レベルとしてシリアライズ可能になります。読取り専用トランザクションではデータベースのスナップショット(.snp)・バージョンが使用されるため、トランザクション中に他のユーザーによって行われる変更やコミットは表示されません。読取り専用トランザクションを使用すると、行ロックのオーバーヘッドを発生させずにデータの読取りが可能です。(RESERVING句で指定する表のスナップショットの保持によるオーバーヘッドは発生しますが、このオーバーヘッドは同等の読取り/書込みトランザクションの場合よりも小さくなります。)
読取り専用トランザクションは本質的に制限されているため、いくつかの制限が課されます。これらの制限は、「使用方法」を参照してください。
READ WRITE
データの取得および更新における整合性を確保するためにSQLのロック・メカニズムを使用するように指定します。デフォルト・トランザクションは、読取り/書込みです。読取り/書込みトランザクション・モードを使用するのは、次の操作が必要な場合です。
- データの挿入、更新または削除
- 取得時に正確であることが保証されているデータの取得
- SQLデータ定義文の使用
読取り/書込みトランザクションでの行の読取り時に、他のユーザーはこの行を更新できません。状況によっては、明示的に読み取っていない行がロックされる場合があります。
- 問合せで索引を使用せずに表をスキャンする場合、分離レベルとしてシリアライズ可能を保持するためにレコード・ストリーム内のすべての行がロックされます。
- 問合せで索引を使用する場合、索引の一部がロックされる場合があります。これには、複数行のロックと同じ効果があります。
RESERVING table-name
RESERVING view-name
トランザクション中にロックする表をリストします。トランザクションでアクセスされるすべての永続実表が含まれます。作成または宣言された一時表は予約できません。RESERVING句を使用して表を指定する場合、アクセスできるのは、予約した表のみです。ただし、RESERVING句でのビューの指定は、ビューの基となる実表の指定と同義です。
timeout-value
特定のトランザクションで他のトランザクションが完了するまで待機する秒数を指定します。この時間は、SET TRANSACTION文で指定したトランザクションでのみ有効です。後続のトランザクションでは、データベースのデフォルトのタイムアウト時間に戻ります。タイムアウト値として0を指定すると、NOWAITになります。トランザクションの開始時には、このトランザクションのロックのタイムアウト時間を決定するために3つの異なる値が使用されます。これらの値は、次のとおりです。
- SET TRANSACTION文に指定されている値
- CREATEまたはALTER DATABASEでの指定に応じてデータベースに格納されている値
- RDM$BIND_LOCK_TIMEOUT_INTERVAL論理名の値
トランザクションのタイムアウト時間は、SET TRANSACTION文に指定されている値と、CREATE DATABASE文に指定されている値のどちらか小さい方の値です。ただし、RDM$BIND_LOCK_TIMEOUT_INTERVAL論理名が定義されている場合、この論理名の値により、CREATE DATABASE文に指定されている値がオーバーライドされます。
USING (tx-options)
USING DEFAULTS
前述のON句の別名によって参照されるデータベースで使用するトランザクション・オプションを指定します。トランザクション、待機モードおよび分離レベル・オプションを明示的に指定したり、DEFAULTSキーワードを使用できます。DEFAULTSの指定は、READ WRITE WAITの指定と同義です。WAIT
NOWAIT
トランザクションでロックされた行が出現したときの処理内容を決定します。デフォルトはWAITです。
- WAITを指定すると、このトランザクションは他のトランザクションが完了するまで待機してから続行されます。必要な場合、他のトランザクションが完了するまで待機せずに、一定の時間が経過した後に続行されるよう指定できます。このタイムアウト時間値は、WAITキーワードの後ろに指定できます。タイムアウト時間値は、秒単位で表されます。
- NOWAITを指定すると、トランザクションでロックされた行が出現したときにエラー・メッセージが返されます。
表6-20は、マルチユーザー・アクセスにおける様々なロック指定の影響の比較を示しています。
表6-20 マルチユーザー・アクセスにおけるロック指定の影響 予約する表のモード 他のユーザーが使用可能な表のアクセス・モード 他のユーザーに対する影響 他のユーザーからの影響 READ WRITE EXCLUSIVE READ
EXCLUSIVE WRITE
EXCLUSIVE DATA DEFINITIONアクセスなし 他のユーザーは表を使用不可能。 影響なし。 PROTECTED READ PROTECTED READ
SHARED READ他のユーザーは表への書込みが不可能。 影響なし。 PROTECTED WRITE SHARED READ 他のユーザーは表への書込みが不可能。トランザクションを終了するまでは、他のユーザーは使用している行の読取りが不可能。 他のユーザーにより読取り/書込みトランザクションで読み取られている行の更新が不可能。 SHARED READ PROTECTED READ
PROTECTED WRITE
SHARED READ
SHARED WRITESHARED WRITEユーザーは使用している行の更新が不可能。 読取り/書込みトランザクションで挿入または更新されている行は、これらのトランザクションが終了するまでは読取りが不可能。 SHARED WRITE SHARED READ
SHARED WRITE他のユーザーは更新している行の読取りまたは更新が不可能。他のユーザーは使用している行の更新が不可能。 他の読取り/書込みトランザクションで使用している行は、読取りまたは更新が不可能。 SHARED DATA DEFINITION SHARED DATA DEFINITION 他のユーザーは予約されている表の書込みまたは読取りが不可能。他のユーザーは、SHARED DATA DEFINITION句を発行すると、表のメタデータを同時に作成および変更可能。 影響なし。 READ ONLY SHARED READ EXCLUSIVE以外のすべて 影響なし。 行に対する変更は表示されない。
SET TRANSACTION文には、複数のデフォルト・レベルがあります。この文全体を省略するか、SET TRANSACTION文を単独で発行すると、トランザクションはREAD WRITE WAIT ISOLATION LEVEL SERIALIZABLEに設定されます。通常、READ WRITEまたはREAD ONLY、RESERVING句の表のリスト、各表の共有モードおよびロック・タイプを指定して、明示的なSET TRANSACTION文を使用する必要があります。SET TRANSACTION文が具体的になるほど、データベース操作が効率的になります。
SET TRANSACTION文によるトランザクションの開始時には、指定されていないトランザクション特性は通常のSQLのデフォルトになります。表6-21は、各オプションおよびオプションの組合せのデフォルトの概要を示しています。
表6-21 SET TRANSACTION文およびDECLARE TRANSACTION文のデフォルト オプション 省略時の設定 トランザクション・モード:
- READ WRITE
- READ ONLY
デフォルトはREAD WRITE。どのトランザクション・モードでも(ある場合)、指定するトランザクション・モードによってデフォルトのロック指定が決まる。 ロック指定:
- RESERVING
- 読取り/書込みトランザクションを指定するときにRESERVING句を含めない場合、各表のロック指定は、データ操作文による最初のアクセス時に決定される。表に対する最初の参照が読取り操作内にある場合、表はSHARED READ用としてロックされる。最初の更新文が発行されると、表はSHARED WRITE用としてロックされる。
- 読取り/書込みトランザクションを指定するときにRESERVING句を含める場合、デフォルトはSHARED。
- トランザクション・モードを指定しないがRESERVING句を含める場合、デフォルトはSHARED。
- 読取り専用トランザクションを指定する場合、RESERVING句を指定するかどうかに関係なく、デフォルトはSHARED READ。
共有モード:
- SHARED
- PROTECTED
- EXCLUSIVE
デフォルトはSHARED。 ロック・タイプ:
- READ
- WRITE
- DATA DEFINITION
- 読取り/書込みトランザクションを指定する場合、デフォルトはWRITE。
- 読取り専用トランザクションを指定する場合、デフォルト(唯一使用可能なロック・タイプ)はREAD。
同時実行オプション:
- ISOLATION LEVEL
READ COMMITTED- ISOLATION LEVEL
REPEATABLE READ- ISOLATION LEVEL
SERIALIZABLE
デフォルトはISOLATION LEVEL
SERIALIZABLE。待機モード:
- WAIT
- NOWAIT
デフォルトはWAIT。
- 指定する各データベースには、次の制限があります。
- READ ONLY句、READ WRITE句またはBATCH UPDATE句のうち、1つのみを使用できます。
- BATCH UPDATEとともに指定できる句はありません。
- WAIT句およびNOWAIT句のうち、1つのみを使用できます。
- ISOLATION LEVELは1回のみ指定できます。
- これらの句は任意の順序で指定できます。
- NAMEに指定できる引用符付き文字列の長さは、最大で255オクテットです。
- オブジェクトがPROTECTEDまたはEXCLUSIVEとして予約されている場合、トランザクションがどの分離レベルでも、この表はノンリピータブル・リード(またはファントム)の対象となりません。ただし、トランザクション全体ではこれらの現象が発生する可能性があります。
- SHARED DATA DEFINITION句を使用する場合、いずれのユーザー(自分を含む)も、同じトランザクションで予約された表に対する問合せまたは更新を実行できません。他のユーザーは、SHARED DATA DEFINITION句を使用しないかぎり、予約された表に対するデータ定義操作を実行できません。
- SHARED DATA DEFINITION句の使用時に他のユーザーとのロック競合を最小限に抑えるには、トランザクションをすぐにコミットします。
- 同じ表で索引を定義するユーザーはすべて、SHARED DATA DEFINITION句を使用して表を予約する必要があります。
- 表に対してEXCLUSIVEアクセスを指定するRESERVING句により、同時索引定義は無効になります。これは、この表にアクセス可能なユーザーは1人のみであるためです。
- PROTECTEDアクセスは、DATA DEFINITION句とともには宣言できません。
- 分離レベルREPEATABLE READを使用する場合、ノンリピータブル・リード現象を防止するために、Oracle Rdbでは必要のない行に対して長時間の読取りロックがかけられる場合があります。分離レベルREPEATABLE READにより、データの競合ではなく索引の競合が軽減されます。
- 分離レベルREAD COMMITTEDで順次スキャンを実行すると、ロック操作の実行回数が増加します。
- 読取り専用トランザクションでは、データベースのスナップショットが使用されます。このため、これらのトランザクションは他のトランザクションの干渉を受けることはなく、デフォルトでは常にシリアライズ可能です。次のSQL文では、競合トランザクション・オプションを指定しており、指定された場合、エラー・メッセージが返されます。