分離レベル

アプリケーション・プロセスがデータにアクセスすると、分離レベル によって、そのデータがロックされる度合い、または他の並行プロセスから分離される度合いが決定します。 分離レベルは、作業単位の期間中有効です。

したがって、アプリケーション・プロセスの分離レベルは、以下を指定します。
  • アプリケーションによって読み取りまたは更新された行が、同時に実行されている他のアプリケーション・プロセスで使用可能になる度合い。
  • 同時に実行されている他のアプリケーション・プロセスの更新アクティビティーによってアプリケーションが影響を受ける度合い。

静的 SQL ステートメントの分離レベルは、パッケージの属性として指定され、 そのパッケージを使用するアプリケーション・プロセスに適用されます。 分離レベルは、ISOLATION バインドまたはプリコンパイル・オプションを設定することにより、プログラム準備処理中に指定されます。 動的 SQL ステートメントの場合、デフォルトの分離レベルは、ステートメントの準備中にパッケージに対して指定された分離レベルです。 SET CURRENT ISOLATION ステートメントを使用すると、セッション内で発行される動的 SQL ステートメントに対して別の分離レベルを指定できます。 詳しくは、CURRENT ISOLATION 特殊レジスターを参照してください。 静的 SQL ステートメントと動的 SQL ステートメントのどちらの場合でも、select-statement 内の isolation-clause は、特殊レジスター (設定されている場合) と BIND オプションの両方の値をオーバーライドします。 詳しくは、select-statement を参照してください。

分離レベルはロックにより施行され、並行アプリケーション・プロセスによるデータ・アクセスは、 使用されるロックのタイプに応じて制限または禁止されます。 宣言済み一時表とその行は、宣言したアプリケーションしかアクセスできないので、ロックされることはありません。

データベース・マネージャーでは、大きく分けて次の 3 つのロック・カテゴリーがサポートされています。
共有 (S)
S ロックでは、並行アプリケーション・プロセスの操作は、データへの読み取り専用操作に限定されます。
更新 (U)
U ロックでは、並行アプリケーション・プロセスは、行を更新する可能性があることを宣言しなかった場合、データに対する読み取り専用操作に限定されます。 データベース・マネージャーは、行を現在見ているプロセスがそれを更新する可能性があると想定します。
排他 (X)
X ロックでは、同時アプリケーション・プロセスがどのような形であれ、そのデータにアクセスできないようにします。 このロック・タイプは、読み取りはできてもデータの変更はできない非コミット読み取り (UR) の分離レベルを持つアプリケーション・プロセスには当てはまりません。
分離レベルとは関係なく、データベース・マネージャーは、 挿入、更新、または削除の対象となる行のすべてに排他ロックをかけます。 したがって、どの分離レベルでも、1 作業単位中にアプリケーション・プロセスによって変更された行は、他のアプリケーション・プロセスによって変更されないことが保証されます。 作業単位が完了すると、データベース・マネージャーは排他ロックを解放します。
データベース・マネージャーは 4 つの分離レベルをサポートします。
注: 一部のホスト・データベース・サーバーは、 コミットなし (NC) 分離レベルをサポートします。 その他のデータベース・サーバーでは、この分離レベルは非コミット読み取り分離レベルに似た動作をします。
注: 更新の消失 (LU) 並行性の問題は、 Db2® 製品の 4 つの分離レベルでは許可されません。

これ以降では、それぞれの分離レベルの詳細について、パフォーマンスへの影響の大きい順に説明されています。ただし、データにアクセスしたりデータを更新したりする場合には、後で説明されているものほど注意が必要になります。

反復可能読み取り (RR)

反復可能読み取り 分離レベルでは、1 つの作業単位 (UOW) の間にアプリケーションが参照する行がすべてロックされます。 アプリケーションが同じ作業単位の中で 2 回 SELECT ステートメントを発行した場合には、いずれの場合も同じ結果が返されます。 RR のもとでは、更新の消失はなく、コミットされていないデータへのアクセス、反復不能読み取り、幻像読み取りは不可能です。

RR では、アプリケーションは、UOW が完了するまでに、必要な回数だけ行の取得および操作を行えます。 しかしそれ以外のアプリケーションは、その UOW が完了するまで、結果セットに影響を与える行を更新、削除、または挿入することができません。 RR 分離レベルの下で実行されるアプリケーションは、コミットされていない他のアプリケーションによる変更は認識できません。 この分離レベルでは、一時表または行ブロッキングが使用されている場合でも、アプリケーションがデータを認識するまで、戻されたすべてのデータが未変更のままであることが保証されます。

取得される行だけでなく、参照されるすべての行がロックされます。 例えば、10 000 個の行をスキャンしてそれらに述部を適用する場合、たとえ 10 行しか適格でなくても、それら 10 000 個の行すべてにロックがかけられます。 照会が再度実行されたとしたらその照会によって参照される行のリストに追加されるであろう行を、別のアプリケーションが追加または更新したりすることはできません。 RR のこの側面は、幻像読み取りを防止します。

RR はかなりの数のロックを獲得する可能性があるため、この数は、locklist および maxlocks データベース構成パラメーターで指定された制限を超える可能性があります。 ロック・エスカレーションが発生する可能性がある場合、オプティマイザーは、ロック・エスカレーションを回避するために、索引スキャン用に単一の表レベル・ロックを獲得することを選択する場合があります。 表レベルのロックをかけたくない場合は、読み取り固定分離レベルを使用します。

Db2が参照制約を評価する際、外部テーブルのスキャンで使用される分離レベルがRRにアップグレードされる場合があります。 このアップグレードは、ユーザーが以前に設定した分離レベルに関係なく行われる可能性があります。 この分離レベルのアップグレードにより、より多くのロックがコミット時まで保持される可能性があり、これにより、デッドロックまたはロック・タイムアウトの可能性が高くなります。 これらの問題を避けるには、参照整合性スキャンが代わりに使用できる、外部キー列のみを含む索引を作成します。

読み取り固定 (RS)

読み取り固定 分離レベルでは、 ある作業単位の間にアプリケーションが取得する行のみにロックをかけます。 RS により、UOW 中に読み取られた適格行が、UOW が完了するまで他のアプリケーション・プロセスによって変更されないことが保証されます。 また RS により、別のアプリケーション・プロセスによって行われた行に対する変更は、その変更がそのプロセスによってコミットされるまで読み取られなくなります。 RS では、コミットされていないデータへのアクセスおよび反復不能読み取りは行えません。 ただし、幻像読み取りは行えます。 幻像読み取りは、古い値は元のアプリケーションの検索条件を満たしていないものの、新しい更新済みの値は検索条件を満たしている行を並行更新することによって、もたらされる場合があります。

例えば幻像読み取り行は、次のような状況で発生することがあります。
  1. アプリケーションのプロセス P1 が、一定の検索条件を満たす行のセット n を読み取る。
  2. 次にアプリケーション・プロセス P2 が、検索条件を満たす 1 行以上の行を挿入し、それらの新規挿入行をコミットする。
  3. P1 が同じ検索条件で行のセットを再度読み取り、元の行と P2 によって挿入された行を両方とも獲得する。

pureScale®Db2、この分離レベルで実行されているアプリケーションは、 異なるメンバで同時に行が更新された場合、以前にコミットされた行の値を拒否することがあります。 この動作をオーバーライドするには、WAIT_FOR_OUTCOME オプションを指定します。

この分離レベルでは、一時表または行ブロッキングが使用されている場合でも、アプリケーションがデータを認識するまで、戻されたすべてのデータが未変更のままであることが保証されます。

RS 分離レベルでは、高度の並行性が提供されると共に、データの表示が一定になります。 この目的を達成するため、オプティマイザーは、ロック・エスカレーションが発生するまで表レベル・ロックがかけられないようにします。

RS 分離レベルは以下の条件下で作動するアプリケーションに適しています。
  • 並行環境で作動する。
  • 1 作業単位の間、適格行が安定状態を保っている必要がある。
  • 1 つの作業単位の間に同じ照会を複数回発行しない。
  • 1 つの作業単位の間に 1 つの照会が複数回発行された場合に、同じ結果セットを得る必要がない。

カーソル固定 (CS)

カーソル固定 分離レベルは、トランザクション中にアクセスされた行を、その行にカーソルが置かれている間、ロックします。 このロックは、次の行がフェッチされるか、トランザクションが終了するまで有効です。 しかし、行の中の何らかのデータが変更された場合、変更がコミットされるまでロックは保持されます。

この分離レベルでは、更新可能なカーソルがある行に置かれている間、他のアプリケーションはその行を更新したり削除したりできません。 CS では、他のアプリケーションの非コミット・データにアクセスすることはできません。 ただし、反復不能読み取りおよび幻像読み取りは可能です。

CS はデフォルトの分離レベルです。 コミットされたデータだけを認識する必要があり、並行性を最大にする場合にこれは適しています。 この分離レベルで実行されるスキャンは、構成パラメーター cur_commit (現在コミット済み) に従って動作します。

Db2 pureScale 環境では、この分離レベルで実行されるアプリケーションは、別のメンバー で行が同時に更新された場合、以前にコミットされた行の値を返すか拒否する可能性があります。 並行アクセス解決設定の WAIT FOR OUTCOME オプションを使用すると、この動作をオーバーライドできます。

注: バージョン 9.7で導入された currently committed セマンティクスでは、以前のようにコミット済みデータのみが返されますが、更新者が行ロックを解放するのをリーダーが待機しなくなりました。 代わりに、読み取り側は、現在コミットされているバージョンに基づくデータ、つまり書き込み操作の開始前のデータを返します。

非コミット読み取り (UR)

非コミット読み取り 分離レベルでは、アプリケーションが他のトランザクションの非コミットの変更にアクセスできます。 さらに UR の場合、別のアプリケーションが表を変更またはドロップしようとするのでない限り、読み取り中の行に別のアプリケーションがアクセスすることが可能です。

UR では、コミットされていないデータへのアクセス、反復不能読み取り、および幻像読み取りが可能です。 この分離レベルは、以下のいずれかの記述が該当する場合に適しています。
  • 読み取り専用表に対して照会を実行する。
  • SELECT ステートメントのみを発行する場合で、かつ、他のアプリケーションによってコミットされたデータが表示されることは問題にならない。
UR の動作は、読み取り専用カーソルと更新可能カーソルとで違います。
  • 読み取り専用カーソルは、他のトランザクションのほとんどの非コミットの変更にアクセスすることができます。
  • トランザクションの処理中は、他のトランザクションによって作成またはドロップされている表、ビュー、および索引は使用できません。 他のトランザクションによるその他の変更は、 コミットまたはロールバックされる前に読み取ることができます。 UR で稼働する更新可能カーソルは、分離レベルが CS であるかのように動作します。
非コミット読み取りを行うアプリケーションが未確定カーソルを使用する場合、実行時に CS 分離レベルを使用する可能性があります。 PREP または BIND コマンドの BLOCKING オプションの値が UNAMBIG (デフォルト) である場合、未確定カーソルが CS にエスカレートされる場合があります。 このエスカレーションを回避するには、以下のいずれかのアクションを適用します。
  • アプリケーション・プログラム内のカーソルが未確定とならないように変更します。 SELECT ステートメントを変更して、FOR READ ONLY 節を組み込みます。
  • アプリケーション・プログラム内のカーソルはそのままにして、未確定のままにします。 ただし、プログラムをプリコンパイルするか、BLOCKING ALL オプションと STATICREADONLY YES オプションを指定してプログラムをバインドして、プログラムの実行時に未確定カーソルが読み取り専用として扱われるようにします。

ISOLATION LEVEL UR の動作は、カラム・オーガナイズ表と行オーガナイズ表で異なる場合があります。

分離レベルの比較

表1は、サポートされている分離レベルを要約したものです。
表 1. 分離レベルの比較
  UR CS RS RR
アプリケーションは、他のアプリケーション・プロセスによって行われた、コミットされていない変更を認識できますか? はい いいえ いいえ いいえ
アプリケーションは、他のアプリケーション・プロセスによって行われた、コミットされていない変更を更新できますか? いいえ いいえ いいえ いいえ
ステートメントの再実行は、他のアプリケーション・プロセスの影響を受ける可能性はありますか? 1 はい はい はい いいえ 2
更新された行が他のアプリケーション・プロセスにより更新される可能性がありますか? 3 いいえ いいえ いいえ いいえ
更新された行が、UR 以外の分離レベルで実行中の他のアプリケーション・プロセスにより読み取られる可能性がありますか? いいえ いいえ いいえ いいえ
更新された行が、UR の分離レベルで実行中の他のアプリケーション・プロセスにより読み取られる可能性がありますか? はい はい はい はい
アクセスされた行が他のアプリケーション・プロセスにより更新される可能性がありますか? 4 はい はい いいえ いいえ
アクセスされた行が他のアプリケーション・プロセスにより読み取られる可能性がありますか? はい はい はい はい
現在行が他のアプリケーション・プロセスにより更新または削除される可能性がありますか? 5 注 6 を参照 注 6 を参照 いいえ いいえ
注:
  1. 幻像読み取り現象 の例には、次のようなものがあります。まず作業単位 UW1 が、ある検索条件を満たす一連の n 個の行を読み取ります。 作業単位 UW2 が、その同じ検索条件を満たす 1 つ以上の行を挿入してからコミットします。 その後、UW1 が同じ検索条件で読み取りを繰り返すと、別の結果セットが認識されます。 最初に読み取られた行と、UW2 によって挿入された行が認識されます。
  2. 読み取りを行ってから次の読み取りを行うまでの間に、ラベル・ベースのアクセス制御 (LBAC) 資格情報が変化した場合、アクセス可能な行が異なるために、2 度目の読み取りの結果は異なる場合があります。
  3. アプリケーションが表に対する読み取りと書き込みの両方を行っている場合、分離レベルはアプリケーションに保護を提供しません。 例えば、アプリケーションが表でカーソルをオープンしてから、同じ表に対して挿入、更新、または削除の操作を実行するとします。 オープン・カーソルでさらに行を取り出してゆくと、アプリケーションが矛盾するデータを見つける場合があります。
  4. 反復不能読み取り現象 の例には、次のようなものがあります。まず、作業単位 UW1 が行を読み取ります。 作業単位 UW2 がその行を変更し、コミットします。 その後、UW1 がその行を再度読み取ると、値が異なる場合があります。
  5. ダーティー読み取り現象 の例には、次のようなものがあります。まず作業単位 UW1 が行を変更します。 UW1 がコミットする前に、作業単位 UW2 がその行を読み取ります。 その後、UW1 が変更をロールバックすると、UW2 は存在しないデータを読み取ったことになります。
  6. UR または CS では、カーソルが更新可能でない場合、 現在行を他のアプリケーション・プロセスによって更新または削除できる場合もあります。 例えば、バッファリングによって、クライアントの現在行とサーバーの現在行との間に相違が生じる場合があります。 さらに、CS で currently committed セマンティクスが使用されている場合、読み取り中の行に保留中のコミットされていない更新が含まれる可能性があります。 この場合は、常に現在コミット済みの行がアプリケーションに返されます。

分離レベルのまとめ

表 2 に、さまざまな分離レベルに関連する並行性の問題をリストします。
表 2. 分離レベルのまとめ
分離レベル コミットしていないデータへのアクセス 反復不能読み取り 幻像読み取り
反復可能読み取り (RR) 不可能 不可能 不可能
読み取り固定 (RS) 不可能 不可能 可能
カーソル固定 (CS) 不可能 可能 可能
非コミット読み取り (UR) 可能 可能 可能
分離レベルは、アプリケーション間の分離の度合いだけでなく、個々のアプリケーションのパフォーマンス特性にも影響します。 ロックの取得と解放に必要な処理リソースとメモリー・リソースは分離レベルによって異なるため、パフォーマンスに影響を与えます。 デッドロックになる可能性も、分離レベルごとに異なります。 表 3 は、アプリケーションの初期分離レベルを選択する際に役立つ単純なヒューリスティックを示しています。
表 3. 分離レベルを選択する指針
アプリケーションのタイプ 高度のデータ安定度が必要 高度のデータ安定度が不要
読み取り/書き込みトランザクション RS CS
読み取り専用トランザクション RR または RS UR