データの整合性を保証できるようにするために、すべてのデータベース管理システム (DBMS) はデータに対してロックを適用します。たとえば、ある編集者が行の更新を開始すると、その行がロックされ、別の編集者がその行を変更するのを防ぎます。トランザクションが完了すると、ロックが解除されます。
各 DBMS は異なる方法でロックを適用し、分離性レベルを解釈します。そのため、ユーザーは、DBMS の動作を調べて、ロックの設定レベル、分離性レベルの設定方法、およびロックのタイムアウトとデッドロックを処理する方法を決定する必要があります。詳細については、使用している DBMS のドキュメントをご参照ください。
また、ArcGIS は、すべての DBMS を同じ方法で操作するわけではありません。そのため、バージョン非対応の編集を実行したときに発生する可能性のある同時実行性の問題は、各種 DBMS 間でわずかに異なります。このトピックでは、ArcGIS に関連して同時実行性とロックがどのように適用されるかについて簡単に説明しますが、データベースのロックは複雑なトピックです。
ArcGIS と分離性レベル
バージョン非対応の編集セッションで Oracle、DB2、または Informix 内のジオデータベースを編集する場合、ArcGIS は、分離性レベルを設定することによる編集環境の変更は行いません。代わりに ArcGIS は、DBMS に設定されている現在の分離性レベルを使用します。そのため、分離性を任意のレベルに設定し、バージョン非対応の編集セッションで編集する際に、そのレベルを使用できます。
ArcGIS 10.4 以降、SQL Server 内のジオデータベースでは、SQL Server のデータベース オプション READ_COMMITTED_SNAPSHOT および ALLOW_SNAPSHOT_ISOLATION を ON に設定する必要があります。バージョン非対応の編集セッションで SQL Server 内のジオデータベースを編集する場合、ArcGIS は、トランザクションに対して READ COMMITTED 分離性レベルを使用します。
以下のセクションでは、一般的な状態で発生する可能性のある同時実行性の問題について説明します。特に明記しない限り、以下の説明では、デフォルトの分離性レベル COMMITTED READ またはそれに相当するレベルが DBMS に設定されていると仮定しています。
Oracle
書き込みが書き込みをブロックする: フィーチャまたはフィーチャのグループに対して、移動や属性の変更などの編集操作を行うと、DBMS は行をロックします。編集セッションを保存するか、保存せずに終了するまで、フィーチャはロックされたままになります。そのため、編集セッションの間に編集しているすべてのフィーチャまたはレコードはロックされます。
2 人のユーザーが同じフィーチャを同時に編集しようとした場合、1 番目の編集者が操作を実行したときにフィーチャがロックされます。この編集者が他のフィーチャで作業していても、このロックは保持され続けます。編集者が変更内容を保存してデータベースにコミットするか、保存しないで編集セッションを終了し、その編集セッション中に実行されたすべての編集内容をロールバックするまで、フィーチャはロックされたままになります。
フィーチャがロックされている間、2 番目の編集者が同じフィーチャを変更しようとします。2 番目の編集者の ArcMap セッションは、ロックが解除されるのを待機して砂時計を表示し、セッションが操作を処理していることを示します。1 番目の編集者が変更内容を保存する (変更内容をデータベースにコミットする) か、変更内容を保存せずに (編集内容をロールバックして) 編集セッションを終了したときにロックが解除されるまで、砂時計は表示され続けます。その後、2 番目の編集者はテーブルを編集できるようになります (つまり、2 番目の編集者の変更内容が 1 番目の編集者の変更内容を上書きします)。
このロックの問題は、以下の状況が発生したとき、2 人の編集者の間で同時に生じる場合もあります。
- 2 人の編集者が同時に編集している。
- 各編集者が現在の編集セッションで行を変更した。
- 各編集者が、他の編集者によってすでに変更されている行を変更しようとしている。
ロックされた行を変更しようとしている 1 番目の編集者には、ArcMap セッションがロックの解除を待機しているため、砂時計が表示されます。2 番目の編集者が、1 番目の編集者によってロックされた行を変更しようとすると、そのとき両方の編集者が互いをブロックしているため、デッドロックと呼ばれる状況が発生します。DBMS は、いずれかの編集者のトランザクションをロールバックすることを直ちに選択し、もう一方の編集者は操作を続行できます。トランザクションがロールバックされた編集者は、最後に編集内容が保存されてから実行したすべての編集をやり直す必要があります。
書き込みが読み取りをブロックしない: データベースに書き込んでいる編集者は、分離性レベルにかかわらず、他のユーザーが同じデータを読み取るのを妨げません。ロックされたデータを読み取っているユーザーまたはアプリケーションにとっては、現在のトランザクションが開始される前に読み取ったように見えます。
読み取りが書き込みをブロックしない: データベースを読み取っているユーザーまたはアプリケーションは、どの分離性レベルでも、他のユーザーが同じデータを変更するのを妨げません。
DB2 と Informix
書き込みが書き込みをブロックする: DB2 および Infomix での書き込みは、Oracle で書き込みが書き込みをブロックするのと同様に、書き込みをブロックします。詳細については、Oracle のセクションの説明をご参照ください。
書き込みが読み取りをブロックする: DB2 および Infomix では、書き込みは、UNCOMMITTED READ より上のすべての分離性レベルで、他のユーザーまたはアプリケーションが同じデータを読み取るのを妨げます。これらの上位の分離性レベルでは、編集内容が保存されるかロールバックされるまでデータがロックされるため、同時実行性の問題が発生する場合があります。編集セッションで作業している間、他のどのユーザーも、編集中のデータを読み取ることができません。これによって、次のような状況が発生します。
- 同じレイヤーを ArcMap に追加した場合、ロックが解除されるまで砂時計が表示され、そのレイヤーは描画されません。
- 編集されているデータを画面移動しようとした場合、ArcMap は、そのロックが解除されるまで待機してから、表示を更新します。
- ロックされたフィーチャを確認する場合、砂時計が表示され、ロックが解除されるまで何も情報が返されません。
読み取りが書き込みをブロックする: DB2 および Infomix では、読み取りは、UNCOMMITTED READ より上のすべての分離性レベルで、編集者が同じデータを変更するのを妨げる場合があります。ただし、実際には、1 行に対する読み取りのロックは、極めて短時間しか保持されないため、ArcGIS ではほとんど目立ちません。データが表示されたときには、ロックはすでに解除されています。データを処理する際に DBMS のカーソルを開き、一度に 1 行を取得し、結果セットを通して反復するアプリケーションにおいてのみ、読み取りが本当に書き込みをブロックすることができます。その場合、DB2 および Infomix は、結果セットを処理されると、ロックの取得および保持を開始します。
PostgreSQL
書き込みが書き込みをブロックする: PostgreSQL では、行を変更した最初のトランザクションがデータベースにコミットされるか、ロールバックされるまで、その行を更新することはできません。2 人の編集者が同じフィーチャを同時に更新または削除しようとした場合、1 番目の編集者が、その行に対する他の編集者の更新をブロックします。1 番目の編集者が変更内容を保存してデータベースにコミットするか、保存しないで編集セッションを終了し、その編集セッション中に実行されたすべての編集内容をロールバックするまで、他の編集者はその行を編集できません。
フィーチャがロックされている間、2 番目の編集者が同じフィーチャを変更しようとします。2 番目の編集者の ArcMap セッションは、ロックが解除されるのを待機して砂時計を表示し、セッションが操作を処理していることを示します。1 番目の編集者が変更内容を保存する (変更内容をデータベースにコミットする) か、変更内容を保存せずに (編集内容をロールバックして) 編集セッションを終了するまで、砂時計は表示され続けます。その後、2 番目の編集者はテーブルを編集できるようになります (つまり、2 番目の編集者の変更内容が 1 番目の編集者の変更内容を上書きします)。
書き込みが読み取りをブロックしない: PostgreSQL の多版型同時実行制御 (MVCC) (データベースのデフォルトで、推奨される動作) を使用している場合、データベースに書き込むトランザクションは、データベースを検索する読み取りをブロックしません。これは、データベースのデフォルトの分離性レベル READ COMMITTED を使用している場合、または分離性レベルを SERIALIZABLE に設定した場合のいずれにも当てはまります。
読み取りが書き込みをブロックしない: データベースに設定した分離性レベルにかかわらず、読み取りはデータをロックしません。
SQL Server
ArcGIS 10.4 以降、SQL Server 内のジオデータベースでは、SQL Server のデータベース オプション READ_COMMITTED_SNAPSHOT および ALLOW_SNAPSHOT_ISOLATION を ON に設定する必要があり、ArcGIS はトランザクションに対して READ COMMITTED 分離性レベルを使用します。READ COMMITTED 分離性レベルの詳細については、SQL Server のドキュメントをご参照ください。
書き込みが書き込みをブロックする: SQL Server での書き込みは、Oracle で書き込みが書き込みをブロックするのと同様に、書き込みをブロックします。
書き込みが読み取りをブロックしない: 読み取りは、ステートメントまたはトランザクションが開始した時点で存在していたコミット済みの行を取得します。
読み取りが書き込みをブロックしない: 行のバージョニングに基づく分離の下で実行されているトランザクションがデータを読み取る場合、読み取り操作は、読み取り中のデータに対する共有されたロックを取得しないため、編集者がデータを変更するのをブロックしません。また、これによって、取得されるロックの数が減少し、リソースをロックするというオーバーヘッドが最小限に抑えられます。行のバージョニングおよびスナップショット分離を使用した読み取りコミット分離は、バージョン対応登録されたデータのステートメントレベルまたはトランザクションレベルの読み取りの整合性を提供するように設計されています。
同時実行性の問題の防止
以下の推奨に従うことで、同時実行性の問題を最小限に抑えることができます。
ロックを考慮してアプリケーションおよびワークフローを設定する
ロックが解除されるのを待機するリクエストは、多くの場合、アプリケーションまたはワークフローの設計が良くないために発生します。アプリケーションまたはワークフローを開発する場合、必ず整理された方法でロックが要求されるようにしてください。これは、すべてのテーブルにわたって更新のシーケンスを標準化することで実現できます。そうすることで、デッドロックを防止します。ロックが保持される時間を減らすには、トランザクションを実行するアプリケーションのロジックまたはワークフローの任意の単位の終了時に、すべてのデータ変更リクエストを発行するのが最も効果的です。
適切な分離性レベルを設定する (Oracle、DB2、Informix)
分離性レベルは、トランザクションがデータをロックする時間に影響を与えます。分離性レベルが高いほど、トランザクションがロックを保持する時間が長くなります。トランザクションがロックを保持する時間が長くなるほどデータの整合性が増しますが、その代償として同時実行性が低下します。アプリケーションが許容できる場合は、分離性レベルを減らして同時実行性を改善できます。
データをバージョン対応登録する
データをバージョン対応登録することによって、同時実行性を改善します。サードパーティのアプリケーションを使用してデータを維持する場合、編集内容をベース テーブルに移行するオプションを使用してデータをバージョン対応登録することを検討してください。そうすることで、サードパーティのアプリケーションが、デフォルト ジオデータベース バージョンに適用された変更内容を表示できるようになりますが、ArcGIS および ArcObjects の機能がアプリケーションに追加されます。そうしないとアプリケーションは、データのバージョンを編集および管理する場合に、同時実行性の問題の影響を受けるか、同時実行性の問題を引き起こします。編集者は、バージョン対応テーブルを変更する場合、ロックを適用しないで、他のユーザーから完全に分離されてデータを編集することができます。