データの整合性を維持するために、すべての 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 人のユーザーの間で同時に発生する可能性があります。
- 2 人のユーザーが同時に同じデータを編集している。
- 2 人のユーザーの編集セッションにすでに更新されたレコードが存在している。
- ユーザーがそれぞれもう一方のユーザーがすでに変更したレコードを変更しようとする。
ロックされたレコードを変更しようとした 1 人目のユーザーに、ロックが解放されるまで ArcMap セッションが待機することを示す砂時計アイコンが表示されます。この時、1 人目のユーザーによってロックされた行を 2 人目のユーザーが変更しようとした時点で、ユーザーが互いの編集操作をブロックし合うことになり、デッドロックと呼ばれる状況が発生します。DBMS は直ちにどちらかのトランザクションのロールバックを選択して、もう一方のトランザクションを引き続き実行できるようにします。トランザクションがロールバックされたユーザーは、最後に編集を保存した時点から編集をやり直す必要があります。
書き込みユーザーは読み取りユーザーをブロックしない: 分離レベルにかかわらず、ユーザーがデータベースに書き込みを行っている間、他のユーザーは同じデータを読み取ることができます。ロックされたデータを読み取るユーザーからは、データはそのユーザーの現在のトランザクションが開始された時点と同じように見えます。
読み取りユーザーは書き込みユーザーをブロックしない:分離レベルにかかわらず、ユーザーがデータベースを読み取っている間、他のユーザーは同じデータを変更することができます。
DB2
書き込みユーザーは書き込みユーザーをブロックする:Oracle で書き込みユーザーが書き込みユーザーをブロックするのと同様に、DB2 では書き込みユーザーが書き込みユーザーをブロックします。詳細については、Oracle の説明をご参照ください。
書き込みユーザーは読み取りユーザーをブロックする:DB2 では、分離レベルが READ UNCOMMITTED 以上の場合、ユーザーが更新しているデータを他のユーザーが読み取ることはできません。このような分離レベルでは、編集がコミットまたはロールバックされるまでデータがロックされるため、編集セッションで更新が行われている間、他のユーザーが編集されたデータを読み取ることができません。これが原因で、次の状況が発生する可能性があります。
- 別のユーザーが編集中のレイヤーを ArcMap に追加した場合には、砂時計アイコンが表示され、ロックが解放されるまでレイヤーは描画されません。
- 別のユーザーが編集中のデータを含む範囲へ画面移動を試みた場合、ArcMap はロックが解放されるのを待ってから表示を更新します。
- ロックされたフィーチャの個別属性表示を別のユーザーが試みた場合、砂時計が表示され、ロックが解放されるまで情報は返されません。
読み取りユーザーは書き込みユーザーをブロックする: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 の振舞いを理解し、適切なロックのレベルや使用する分離レベルを判断し、ロック要求のタイムアウトやデッドロックに対処する必要があります。