web-dev-qa-db-ja.com

SQL Serverで行レベルのロックを強制することは可能ですか?

SQL Serverで行レベルとページレベルのロックをオフにする方法はわかりますが、SQL Serverに行レベルのロックを使用させる方法は見つかりません。 SQL Serverで強制的に行レベルのロックを使用し、ページレベルのロックを使用しないようにする方法はありますか?

54
Elan

ROWLOCKヒントを使用できますが、リソースが不足している場合はAFAIK SQLがエスカレーションすることを決定する場合があります

ドコから

ROWLOCKページまたはテーブルのロックが通常取得されるときに行ロックが取得されることを指定します。 SNAPSHOT分離レベルで動作するトランザクションで指定された場合、ROWLOCKがUPDLOCKやHOLDLOCKなどのロックを必要とする他のテーブルヒントと組み合わされない限り、行ロックは取得されません。

そして

行レベルのロックを取得するロックヒントROWLOCK、UPDLOCK、およびXLOCKは、実際のデータ行ではなくインデックスキーにロックを設定する場合があります。たとえば、テーブルに非クラスター化インデックスがあり、ロックヒントを使用するSELECTステートメントがカバーインデックスによって処理される場合、ロックはベーステーブルのデータ行ではなく、カバーインデックスのインデックスキーで取得されます。

そして最後に これは、SQL Server 2008で変更されたSQL Server 2005のロックエスカレーションに関するかなり詳細な説明を提供します。

また、非常に詳細な情報もあります。 データベースエンジンのロック (オンラインの書籍)

だから、一般的に

UPDATE
Employees WITH (ROWLOCK)
SET Name='Mr Bean'
WHERE Age>93

大丈夫ですが、インデックスとサーバーの負荷によっては、ページロックにエスカレートする可能性があります。

32
Sam Saffron

ALTER/CREATE INDEX のALLOW_PAGE_LOCKS句を使用します。

ALTER INDEX indexname ON tablename SET (ALLOW_PAGE_LOCKS = OFF);
14
Remus Rusanu

オプティマイザに強制的に何もさせることはできませんが、ガイドすることはできます。

UPDATE
Employees WITH (ROWLOCK)
SET Name='Mr Bean'
WHERE Age>93

参照- ロックとヒントによるSQL Serverの制御

8
mdma