データベース エンジンのロック

Microsoft SQL Server データベース エンジンでは、"ロック" というメカニズムを使用して、複数のユーザーによる同じデータへの同時アクセスが同期されます。

トランザクションでは、データの読み取りや変更など、データの現在の状態に対する依存関係を取得する前に、そのトランザクションを、別のトランザクションで同じデータが変更される影響から保護する必要があります。トランザクションでは、データのロックを要求することにより、この問題に対処しています。ロックには、共有ロックや排他ロックなど複数のモードがあります。ロック モードは、データに対するトランザクションの依存関係の度合いを定義します。別のトランザクションに既に許可されているロックのモードと競合するロックを、トランザクションに許可することはできません。トランザクションで、あるデータに対して既に許可されたロックと競合するロックのモードが要求された場合、データベース エンジンのインスタンスにより、既に許可されたロックが解放されるまで、要求を行ったトランザクションは保留されます。

トランザクションでデータが変更される場合、そのトランザクションでは、トランザクションが完了するまでロックを保持して、データの変更を保護します。トランザクションが読み取り操作を保護するために取得したロックの保持期間は、トランザクションの分離レベルの設定により異なります。トランザクションで保持されているすべてのロックは、トランザクションが完了 (コミットまたはロールバック) した時点で解放されます。

通常、アプリケーションから、ロックが直接要求されることはありません。ロックは、データベース エンジンのロック マネージャにより、内部で管理されます。データベース エンジンのインスタンスで Transact-SQL ステートメントが処理されると、データベース エンジンのクエリ プロセッサにより、アクセスするリソースが判断されます。クエリ プロセッサでは、アクセスの種類とトランザクションの分離レベルの設定に基づいて、各リソースを保護するために必要なロックの種類が決定されます。その後、クエリ プロセッサから、ロック マネージャに適切なロックが要求されます。ロック マネージャでは、別のトランザクションで保持されているロックに競合するロックがない場合、要求されたロックを許可します。

次の表に、ロックの主要な概念を説明するトピックの一覧を示します。

トピック

説明

ロックの粒度と階層

ロックは、行、ページ、インデックス、テーブル、データベースなど、さまざまなリソースに対して要求できます。操作によっては、複数レベルの粒度のロックを取得して、ロック階層を形成することが必要になる場合があります。

ロック モード

ロックには、ロックされたリソースへの他のトランザクションによるアクセス レベルを指定する複数のモードがあります。

ロックの互換性 (データベース エンジン)

トランザクションのロック モードが競合しなければ、同じリソースに対して複数のトランザクションでロックを同時に取得することができます。あるトランザクションで既存のロックと競合するロック モードが要求された場合、このトランザクションは既存のロックが解放されるまで保留されます。

キー範囲ロック

SERIALIZABLE 分離レベルで実行されているトランザクションでは、一定範囲のキーに対するロックを取得することで、ファントム挿入やファントム削除の発生を防ぐことができます。

ロックのエスカレーション (データベース エンジン)

1 つのトランザクションで多数の行またはページ ロックが取得された場合、データベース エンジンでは、そのトランザクションに対してテーブル ロックを許可し、下位レベルのロックをすべて解放してロックのオーバーヘッドを最小限に抑える場合があります。

動的ロック

データベース エンジンでは、オプティマイザによる Transact-SQL ステートメントが参照する行数の算出に基づいて、ロックの粒度レベルが動的に選択されます。

ロックに関する情報の表示 (データベース エンジン)

データベース エンジンとこれに関連する API には、インスタンスやデータベースで現在保持されているロックについての情報を表示するための、いくつかのメカニズムが用意されています。

デッドロック

デッドロックは、2 つのタスクのそれぞれがもう一方のタスクで必要なリソースのロックを保持しているために、永続的に互いをブロックしている場合に発生します。