同時実行性とロック

データの整合性を維持するために、すべての DBMS(Database Management System)はデータにロックを適用します。たとえば、あるユーザが行の更新を開始した場合、それらの行は別のユーザによって変更されないようにロックされます。トランザクションが完了すると、ロックは解放されます。

DBMS ごとに、ロックを適用する方法と分離レベルを実装する方法は異なります。したがって、ArcGIS はすべての DBMS に同じように対応するわけではありません。このため、バージョン非対応編集を実行するときに発生する同時実行性の問題は、DBMS によって少しずつ異なります。このトピックでは、ArcGIS に適用される DBMS ごとの同時実行性とロックについて簡単に説明します。詳細については、DBMS のドキュメントをご参照ください。

ArcGIS と分離レベル

Oracle または DB2 のジオデータベースにおいて、バージョン非対応編集を行う際には、他のアプリケーションを操作するときと同じ DBMS のロック メカニズムが適用されます。ArcGIS が独自に分離レベルを設定することはありません。代わりに、DBMS に設定されている既存の分離レベルが使用されます。このため、DBMS に任意の分離レベルを設定し、バージョン非対応の編集セッションでその分離レベルを利用することができます。

SQL Server のジオデータベースにおいてバージョン非対応編集を行う際には、トランザクションが開始される前に、分離レベルが READ UNCOMMITTED に設定されます。この振舞いを変更することはできません。事前に分離レベルを別のレベルに設定している場合でも、トランザクションを開始する前に分離レベルが READ UNCOMMITTED に再設定されます。

次のセクションでは、一般的な状況下で発生し得る同時実行性の問題について説明します。特に明記しない限り、これらの説明では、DBMS の分離レベルがデフォルトの READ COMMITTED(またはそれに相当するレベル)に設定されていることを前提とします。

Oracle

書き込みユーザは書き込みユーザをブロックする:フィーチャまたはフィーチャのグループに対して移動や属性の変更といった編集操作を実行すると、DBMS によって行がロックされます。ユーザが編集を保存するか、保存せずに編集セッションを終了するまで、フィーチャはロックされたままとなります。したがって、編集対象のフィーチャまたはレコードは、編集セッションが終了するまでロックされます。

2 人のユーザが同じフィーチャを同時に編集しようとした場合、そのフィーチャは最初のユーザが編集操作を完了したときにロックされます。このロックは、そのユーザが他のフィーチャを操作している間も維持されます。ユーザが編集を保存する(変更がデータベースにコミットされる)か、保存せずに編集セッションを終了する(その編集セッションで実行した編集がすべてロールバックされる)まで、フィーチャはロックされたままとなります。

フィーチャがロックされている間に、2 人目のユーザが同じフィーチャを変更しようとすると、2 人目のユーザの ArcMap セッションはロックの解放待ちとなり、砂時計が表示されます。1 人目のユーザが編集を保存(変更をデータベースにコミット)するか編集を保存せずに編集セッションを終了(編集をロールバック)してロックを解放するまで、砂時計アイコンが表示されます。ロックが解放されると、2人目のユーザの画面で砂時計アイコンが消え、編集操作が可能になります(2 人目のユーザの編集が 1 人目のユーザの編集を上書きすることに注意してください。)

このロック問題は、次の状況下にある 2 人のユーザの間で同時に発生する可能性があります。

ロックされたレコードを変更しようとした 1 人目のユーザに、ロックが解放されるまで ArcMap セッションが待機することを示す砂時計アイコンが表示されます。この時、1 人目のユーザによってロックされた行を 2 人目のユーザが変更しようとした時点で、ユーザが互いの編集操作をブロックし合うことになり、デッドロックと呼ばれる状況が発生します。DBMS は直ちにどちらかのトランザクションのロールバックを選択して、もう一方のトランザクションを引き続き実行できるようにします。トランザクションがロールバックされたユーザは、最後に編集を保存した時点から編集をやり直す必要があります。

書き込みユーザは読み取りユーザをブロックしない: 分離レベルにかかわらず、ユーザがデータベースに書き込みを行っている間、他のユーザは同じデータを読み取ることができます。ロックされたデータを読み取るユーザからは、データはそのユーザの現在のトランザクションが開始された時点と同じように見えます。

読み取りユーザは書き込みユーザをブロックしない:分離レベルにかかわらず、ユーザがデータベースを読み取っている間、他のユーザは同じデータを変更することができます。

DB2

書き込みユーザは書き込みユーザをブロックする:Oracle で書き込みユーザが書き込みユーザをブロックするのと同様に、DB2 では書き込みユーザが書き込みユーザをブロックします。詳細については、Oracle の説明をご参照ください。

書き込みユーザは読み取りユーザをブロックする:DB2 では、分離レベルが READ UNCOMMITTED 以上の場合、ユーザが更新しているデータを他のユーザが読み取ることはできません。このような分離レベルでは、編集がコミットまたはロールバックされるまでデータがロックされるため、編集セッションで更新が行われている間、他のユーザが編集されたデータを読み取ることができません。これが原因で、次の状況が発生する可能性があります。

読み取りユーザは書き込みユーザをブロックする:DB2 では、分離レベルが READ UNCOMMITTED 以上の場合、ユーザが読み取っているデータを他のユーザが変更することはできません。ただし、行の読み取りロックが維持される期間は非常に短いため(データが表示された時点でロックはすでに解放されています)、ArcGIS においてこの現象は非常に稀なケースとなります。実際に読み取りユーザによって書き込みユーザがブロックされるのは、DBMS でカーソルを開いて、行を 1 行ずつ取り出し、結果セットをループにかけてデータを処理する場合です。この場合、DB2 は結果セットを処理する間、ロックを取得します。

PostgreSQL

書き込みユーザは書き込みユーザをブロックする:PostgreSQL の場合、行を変更するトランザクションがデータベースにコミットされるかロールバックされるまで、行は更新されません。2 人のユーザが同じフィーチャを同時に編集しようとした場合、最初のユーザがその行の更新をブロックします。最初のユーザが編集を保存する(変更がデータベースにコミットされる)か、編集を保存せずに編集セッションを終了する(その編集セッションで実行した編集がすべてロールバックされる)まで、2 人目のユーザはこの行を編集できません。

フィーチャがロックされている間に、2 人目のユーザが同じフィーチャを変更しようとすると、2 人目のユーザの ArcMap セッションはロックの解放待ちとなり、砂時計が表示されます。1 人目のユーザが変更を保存(変更をデータベースにコミット)するか編集を保存せずにセッションを終了(編集をロールバック)するまで、砂時計アイコンが表示されます。ロックが解放されると、2人目のユーザの画面で砂時計アイコンが消え、編集操作が可能になります(2 人目のユーザの編集が 1 人目のユーザの編集を上書きすることに注意してください。)

書き込みユーザは読み取りユーザをブロックしない:PostgreSQL では多版型同時実行制御(MVCC)の使用がデフォルトであり、推奨されていますが、その場合データベースに書き込むユーザ トランザクションによって読み取りユーザのデータベース クエリがブロックされることはありません。データベースで、デフォルトの READ COMMITTED 分離レベルを使用する場合、または分離レベルを SERIALIZABLE に設定した場合にも同様です。

読み取りユーザは書き込みユーザをブロックしない:データベースでの分離レベルの設定にかかわらず、読み取りユーザはデータをロックしません。

SQL Server

ArcGIS は、SQL Server のジオデータベースでトランザクションを開始する前に、分離レベルを READ UNCOMMITTED に設定します。ここでは、ArcGIS のコンテキストでどのような同時実行性の問題が発生するかについて説明します。READ UNCOMMITTED 分離レベルの詳細については、SQL Server のドキュメントを参照してください。

書き込みユーザは書き込みユーザをブロックする:Oracle で書き込みユーザが書き込みユーザをブロックするのと同様に、SQL Server では書き込みユーザが書き込みユーザをブロックします。詳細については、Oracle の説明をご参照ください。

書き込みユーザは読み取りユーザをブロックしない:ArcGIS は、トランザクションを開始する前に分離レベルを READ UNCOMMITTED に設定するので、SQL Server ジオデータベースでは、書き込みユーザによって読み取りユーザがブロックされることはありません。ただし、あるユーザが変更しているデータを他のユーザが読み取る際に、変更されているがコミットされていないデータを読み取る可能性があります。これはダーティ リードと呼ばれるもので、クエリから次のようなデータが返される可能性があります。

読み取りユーザは書き込みユーザをブロックしない:ArcGIS は、トランザクションを開始する前に分離レベルを READ UNCOMMITTED に設定するので、SQL Server ジオデータベースでは、読み取りユーザによって書き込みユーザがブロックされることはありません。

同時実行性問題の回避

ここでは、同時実行性における問題の回避方法について説明します。

ロックを考慮に入れてアプリケーションとワークフローを設計する:ロック要求がロックの解放を待機する問題は、多くの場合、アプリケーションやワークフローが正しく設計されていないことに起因します。アプリケーションやワークフローを設計する際には、ロックが計画的に要求されるように考慮する必要があります。そのためには、すべてのテーブルにわたって一連の更新処理を標準化することが有効です。これにより、デッドロックが回避されます。ロックが保持される時間を短縮するには、一般的にはトランザクションを実行するアプリケーション ロジックまたはワークフローの最後に、すべてのデータ変更要求を発行するのが最も効果的です。

適切な分離レベルを設定する(Oracle、DB2):分離レベルは、トランザクションがデータをロックする時間の長さを左右します。分離レベルが高くなればなるほど、トランザクションがデータをロックする時間は長くなります。トランザクションがデータをロックする時間が長くなればなるほど、データの整合性は高まりますが、同時実行性が損なわれるという代償が伴います。アプリケーションやワークフローの設計上問題が発生しないのであれば、分離レベルを下げて同時実行性を向上させることを検討します。

データをバージョン対応登録する:ベース テーブル移行オプションを使用してデータをバージョン対応レイヤとして登録することにより、同時実行性を向上させます。これにより、ArcGIS 以外のアプリケーションで引き続きデータを管理できるとともに、ArcGIS と ArcObjects アプリケーションのユーザはデータの同時実行性の問題を意識せずに、データのバージョンを編集して管理できるようになります。バージョン編集では更新対象フィーチャのロックを取得せずに、他のユーザから完全に分離された状態でデータを編集することができます。

データベースのロックは複雑なトピックであり、かつ、DBMS によってロックを実行する方法は異なります。使用している DBMS の振舞いを理解し、適切なロックのレベルや使用する分離レベルを判断し、ロック要求のタイムアウトやデッドロックに対処する必要があります。

関連トピック

10/8/2012