管理の手引き


並行性

リレーショナル・データベースにおいて、 複数のユーザーがデータにアクセスし変更したとしても、 データの保全性は保たれなければなりません。 並行性 とは、 複数の対話式ユーザーまたはアプリケーション・プログラムが同時にリソースを共用することです。 データベース・マネージャーはこのアクセスを制御し、次のような望ましくない結果を防ぎます。

分離レベル は、データがアクセスされている間、 データが他の処理からどのようにロックされ分離されるかを決めるものです。 分離レベルは、作業単位の持続期間中で有効です。 WITH HOLD 文節を使用して宣言されたカーソルを使用するアプリケーションは、 OPEN CURSOR が実行された作業単位の持続期間中、選択した分離レベルを保ちます。 (詳細については、SQL 解説書 を参照してください。) 分離レベルの指定方法については、分離レベルの指定を参照してください。

DB2 でサポートする分離レベルは、次のとおりです。

(一部の DRDA データベース・サーバーは コミットなし 分離レベルをサポートすることに注意してください。 その他のデータベースでは、コミットされない読み取りの分離レベルと同様に動作します。 この分離レベルの説明については、 SQL 解説書 を参照してください。)

次のものも参照してください。

連合データベース・システムでは、 アプリケーションやユーザーが 1 つのステートメント内で 2 つ以上のデータベース管理システム (DBMS) またはデータベースを参照する SQL ステートメントを実行依頼できます。 DB2 連合システムは、データベース・オブジェクトの位置透過性を提供します。 たとえば、表および視点についての情報が移動する場合に、 その情報への参照 (ニックネームと呼ばれる) を、 その情報を要求するアプリケーションに変更を加えることなく更新することができます。 アプリケーションがニックネームにアクセスすると、 DB2 はデータ・ソース・データベース・マネージャーのデータの並行性制御プロトコルにより、 分離レベルを保証します。 (データ・ソースは、DBMS とデータで構成されています。) DB2 は要求されたデータ・ソースでの分離レベルを論理的に同等のものと一致させようと試みますが、 結果はデータ・ソースの機能によって異なることがあります。 ニックネームにアクセスするアプリケーションの作成については、 アプリケーション開発の手引き を参照してください。

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

反復可能読み取り

反復可能読み取り (RR) では、 ある作業単位の中でアプリケーションが参照する行すべてにロックがかけられます。 反復可能読み取りを使用した場合、 カーソルがオープンされたのと同じ作業単位の中でアプリケーションが同じ SELECT ステートメントを 2 回発行しても、 それぞれ同じ結果になります。 反復可能読み取りを使用すると、更新が失われている場合、 コミットされていないデータおよび幻像行へのアクセスはできなくなります。

反復可能読み取りアプリケーションは、その作業単位が完了するまでに、 必要な回数だけ行の検索および操作を行えます。 しかしそれ以外のアプリケーションは、その作業単位が完了するまで、 結果表に影響を与える可能性のある行を更新、削除、 または挿入することができなくなります。 反復可能読み取りアプリケーションでは、 他のアプリケーションの非コミット変更を表示することはできません。

反復可能読み取りを使用すると、検索中の行だけでなく、 参照される行すべてにロックがかかります。 適正にロックがかけられることによって、 最初の照会で参照した後で再び照会を実行したときに、 その間に別のアプリケーションが行を挿入または追加するということはできなくなります。 これにより、幻像現象が発生しなくなります。 つまり、10 000 個の行を走査してそれらに述部を適用する場合、 10 行しか適格でなくても、それら 10 000 個の行すべてにロックがかけられます。
注:反復可能読み取りの分離レベルでは、 返されるデータすべてをアプリケーションが見る までは、 一時表や行ブロック化が使用されている場合であっても、 それらの行はすべて未変更のままになっています。

反復可能読み取りでは、相当数のロックを獲得し保持するため、それらのロックが、 locklistmaxlocks の構成パラメーターの結果として使用可能なロックの数を超えることがあります。 (自動調整前のロック・リストの最大パーセント (maxlocks)ロック・リストの最大記憶域 (locklist)を参照。) ロック・エスカレーションが非常に発生しやすいと判断した場合、 ロック・エスカレーションを避けるために、 最適化プログラムは索引の走査のために単一表レベル・ロックを直接獲得することがあります。 (ロック・エスカレーションについては、ロック・エスカレーションを参照してください。) これは、データベース・マネージャーが LOCK TABLE ステートメントを発行したかのように機能します。 表レベルのロックをかけたくない場合は、 トランザクションに十分な数のロックを使用できるようにするか、 または"読み取り固定"分離レベルを使用します。

読み取り固定

読み取り固定 (RS) では、 ある作業単位においてアプリケーションが検索する行にロックをかけます。 これにより、ある作業単位で適格とされて読み取られた行は、 その作業単位が完了するまで他のアプリケーションによって変更されないようになり、 また他のアプリケーションのプロセスによって変更されたすべての行は、 そのプロセスによって変更がコミットされるまで読み取られないようになります。 つまり、「反復不能読み取り」の処理はあり得なくなります

反復可能読み取りとは異なり、読み取り固定では、 アプリケーションが同じ照会を 2 回以上出すと、 新たな幻像 行 (幻像読み取り現象) が生じる可能性があります。 前述の 10 000 個の行を走査する例を考えると、 読み取り固定を使う場合は適格な行だけがロックされます。 したがって、読み取り固定を使用すると、10 行だけが検索され、 ロックはそれら 10 行だけにしかかけられません。 これとは対照的に反復可能読み取りを使用すると、この例の場合は、 ロックが 10 000 行すべてにかけられます。 保持することができるロックは、共用、次回共用、更新、または排他ロックです。 (ロック属性については、ロックの属性 を参照してください。)
注:読み取り固定分離レベルを使う場合、 一時表や行ブロック化を使用する場合でも、 返されるデータすべてをアプリケーションが見る までは、 それらのデータはすべて未変更になっています。

読み取り固定分離レベルの目的は、データの表示を一定にするとともに、 高度の並行性を提供することにあります。 この目的を達成するため、最適化プログラムは、 ロック・エスカレーションが発生するまで表レベル・ロックがかけられないようにします。 (ロック・エスカレーションについては、ロック・エスカレーションを参照してください。)

次のことすべてを行うアプリケーションでは、読み取り固定分離レベルが最適です。

カーソル固定

カーソル固定 (CS) は、 アプリケーションのトランザクションがアクセスする行にカーソルがある間、 その行をロックします。 このロックは、次の行が取り出されるか、 またはトランザクションが終了する時まで有効です。 しかし、行の中の何らかのデータが変更された場合、 変更がデータベースにコミットされるまで、ロックが保持されていなければなりません。

カーソル固定アプリケーションが検索した行に更新可能なカーソルがある間、 他のアプリケーションはその行を更新したり削除したりできません。 カーソル固定のアプリケーションでは、 他のアプリケーションによる非コミット変更を見ることができません。

前述の 10 000 行を走査する例を考えてみると、カーソル固定を使う場合は、 現在カーソルが位置している行だけにロックがかかります。 ロックは、その行から移動すると (その行を更新しなければ) 解除されます。

カーソル固定を使うと、反復不能読み取りと幻像読み取り現象は両方とも発生する可能性があります。 カーソル固定は省略時の分離レベルですが、 コミットされた行だけを他のアプリケーションから見る間は並行性を最大にしたいという場合に、 ぜひ使用するようにしてください。

非コミット読み取り

非コミット読み取り (UR) では、 アプリケーションが他のアプリケーションの非コミットの変更にアクセスできます。 アプリケーションは、 他のアプリケーションが表を除去または変更しようとするのでない限り、 読み取り中の行について他のアプリケーションに対するロックをかけません。 非コミット読み取りの動作は、読み取り専用カーソルと更新可能カーソルとで違います。

読み取り専用カーソルは、 他のトランザクションのほとんどの非コミットの変更にアクセスすることができます。 しかし、トランザクションの処理中に、 他のトランザクションによって作成または除去されている表、視点、 および索引にアクセスすることはできません。 他のトランザクションによるその他の変更は、 コミットまたはロールバックされる前に読み取ることができます。
注:非コミット読み取り分離レベルで更新可能な操作を行っているカーソルは、 カーソル固定分離レベルの場合と同じ働きをします。

前述の 10 000 行を走査する例を考えてみると、 非コミット読み取りを使う場合は、ロックが獲得されません。 つまり行にロックがかからなくなります。

非コミット読み取りを使用すると、 反復不能読み取りと幻像読み取り現象の両方とも発生する可能性があります。

非コミット読み取り分離レベルは、読み取り専用表に対して、 あるいは選択ステートメントのみを実行しており、 かつ他のアプリケーションから非コミット・データを見るかどうかが問題にはならない場合に、 最もよく用いられています。

分離レベルの選択

表 36 には、 アプリケーション開発の手引き に示されている望ましくない影響に関連して、 さまざまな分離レベルが要約されています。

表 36. 分離レベルのまとめ
分離レベル 非コミット・ データへの アクセス 反復不能 読み取り 幻像読み取り 現象
反復可能読み取り (RR) 不可能 不可能 不可能
読み取り固定 (RS) 不可能 不可能 可能
カーソル固定 (CS) 不可能 可能 可能
非コミット読み取り (UR) 可能 可能 可能

表 37 には、 ご使用のアプリケーションの初期分離レベルを選択する上で役立つ簡単な発見的手法が収められています。 次の表を参考に、 必要な要件により適した値を選択する上で考慮すべきさまざまなレベルの要因について述べたこれまでの説明を参照してください。


表 37. 分離レベルを選択する指針
アプリケーションのタイプ 高度のデータ安定度が必要 高度のデータ安定度が不要
読み書きトランザクション RS CS
読み取り専用トランザクション RR または RS UR

アプリケーションに適した分離レベルを選択することは、 そのアプリケーションに許容されていない現象を回避するためにとても重要です。 分離レベルは、アプリケーション間の分離の程度に影響を与えるだけでなく、 ロックの獲得と解放に必要な CPU とメモリーのリソースが分離レベルごとに異なるため、 個々のアプリケーションのパフォーマンス特性にも影響を与えます。 デッドロック状態になる可能性は、分離レベルごとに異なります。

分離レベルの指定

分離レベルは、プリコンパイル時、 またはアプリケーションがデータベースにバインドされるときに指定されます。 サポートされるコンパイル言語で作成されたアプリケーションの場合、 コマンド行プロセッサーの PREP または BIND コマンドの ISOLATION オプションを使用します。 分離レベルは、PREP または BIND の API を使って指定することもできます。 分離レベルを指定しない場合、省略時値としてカーソル固定が使用されます。

プリコンパイル時にバインド・ファイルが作成される場合、 分離レベルはそのバインド・ファイル内に保管されます。 バインド時に分離レベルが指定されない場合の省略時値は、 プリコンパイル時に使用された分離レベルです。

次の照会を実行すると、 パッケージの分離レベルを調べることができます。

     SELECT ISOLATION FROM SYSCAT.PACKAGES
       WHERE PKGNAME = 'XXXXXXXX'
       AND PKGSCHEMA = 'YYYYYYYY'

XXXXXXXX はパッケージの名前、 YYYYYYYY はパッケージのスキーマ名です。 これらの名前は両方ともすべて大文字でなければなりません。

データベースを作成すると、 REXX に含まれる SQL のさまざまな分離レベルのサポートに使用される複数のバインド・ファイルがデータベースにバインドされます (REXX をサポートするサーバーで)。 他のコマンド行プロセッサー・パッケージも、 データベースの作成時にデータベースにバインドされます。 バインド・ファイルの詳細については、 アプリケーション開発の手引き を参照してください。

データベースへの REXX とコマンド行プロセッサーによる接続では、 カーソル固定の省略時分離レベルが使用されます。 異なる分離レベルに変更しても、接続状態は変更しません。 このコマンドは、CONNECTABLE AND UNCONNECTED 状態または IMPLICITLY CONNECTABLE 状態のときに実行する必要があります。 (接続状態の詳細については、 SQL 解説書 の『CONNECT TO ステートメント』を参照してください。) このコマンドを出すと、データベースには接続できなくなります。

REXX アプリケーションで SQLISL REXX 変数の値を調べることによって、 使用される分離レベルを調べることができます。 その値は、CHANGE SQLISL コマンドが実行されるたびに更新されます。

DB2_RR_TO_RS プロファイル登録変数を使用すると、 ユーザー表への反復可能読み取り (RR) 分離レベルを不能にできます。 RR 分離レベルの意味体系が必須ではない環境では、 db2set を使用してこの登録値を "YES" に設定できます。 有効にするには、データベースを停止してから開始する必要があります。 db2start の後で、この変更はインスタンス全体に影響を与えるようになります。 この登録値がいったん設定されたならば、 ユーザー表への RR を使用したアクセスが要求されても要求の内容が内部的に修正されて、 読み取り固定 (RS) 分離レベルが代わりに使用されます。 この処理を行う前に警告は出されません。

コマンド行プロセッサーを使用している場合には、 CHANGE ISOLATION LEVEL コマンドを使用して分離レベルを変更できます。 詳細については、コマンド解説書 を参照してください。

DB2 コール・レベル・インターフェース (DB2 CLI) の場合は、 DB2 CLI 構成の一部として分離レベルを変更できます。 実行時の CLI では、 SQLSetConnectAttr 関数を SQL_ATTR_TXN_ISOLATION 属性と組み合わせて使用します。 これによって、 ConnectionHandle で参照される現行接続のトランザクション分離レベルが設定されます。 db2cli.ini ファイルでは、TXNISOLATION キーワードも使用できます。
注:JDBC および SQLJ は、DB2 上の CLI を使用して実装されています。 つまり、db2cli.ini の設定は、 JDBC や SQLJ を使用して作成および実行されることに影響します。 詳細については、コール・レベル・インターフェースの手引きおよび解説書 を参照してください。

実行時に JDBC または SQLJ を使用する場合は、 java.sql インターフェース接続の setTransactionIsolation メソッドを使用して、 分離レベルを確立することができます。 詳しくは、アプリケーション開発の手引き の『Java でのプログラミング』の章を参照してください。

SQLJ を使用していて、 db2profc SQLJ 最適化プログラムを実行している場合には、 パッケージが作成されます。 このパッケージの最後のオプションに、 使用する分離レベルを指定することができます。 詳しくは、アプリケーション開発の手引き の『Java でのプログラミング』の章を参照してください。

さらに、多くの商業目的で作成されたアプリケーションでも、 分離レベルを選択するための手段が提供されています。 詳細については、コール・レベル・インターフェースの手引きおよび解説書 を参照してください。

宣言済み一時表および並行性

宣言済み一時表は、 これらを宣言したアプリケーションでのみ使用できるため、 並行性の問題はありません。 このタイプの表は、 アプリケーションがこれを宣言してから、 これを完了または切断するまでのあいだのみ存在します。


[ ページのトップ | 前ページ | 次ページ | 目次 | 索引 ]