UPDLOCKブロックが選択するのはなぜですか?ロック互換性マトリックスは、N
を明確に示しています 競合なしのように、S/UおよびU/Sの競合の場合 。
HOLDLOCKヒントについては、ドキュメントに次のように記載されています。
HOLDLOCK:SERIALIZABLEと同等です。詳細については、このトピックの後半のSERIALIZABLEを参照してください。
...
SERIALIZABLE:...スキャンは、SERIALIZABLE分離レベルで実行されているトランザクションと同じセマンティクスで実行されます...
トランザクション分離レベルのトピックでは、SERIALIZABLEの意味について説明しています。
現在のトランザクションが完了するまで、他のトランザクションは現在のトランザクションによって読み取られたデータを変更できません。
他のトランザクションは、現在のトランザクションが完了するまで、currenttransaction内のステートメントによって読み取られるキーの範囲に含まれるキー値を持つ新しい行を挿入できません。
したがって、表示される動作は、製品ドキュメントによって完全に説明されています。
- UPDLOCKは、同時SELECTまたはINSERTをブロックしませんが、T1によって選択された行のUPDATEまたはDELETEをブロックします
- HOLDLOCKはSERALIZABLEを意味するため、SELECTSを許可しますが、T1によって選択された行のUPDATEとDELETESもブロックします。 T1によって選択された範囲内の任意のINSERT(つまり、テーブル全体であるため、 any 挿入)。
- (UPDLOCK、HOLDLOCK):実験では、上記の場合に加えて何がブロックされるか、つまりT2でのUPDLOCKを使用した別のトランザクションは示されていません。 :
SELECT * FROM dbo.Test WITH (UPDLOCK) WHERE ...
- TABLOCKX説明の必要はありません
本当の問題は、何を達成しようとしているのかです。 ?ロックのセマンティクスを完全に完全に理解せずにロックのヒントを試してみると、問題が発生します...
OP編集後:
テーブルから行を選択し、処理中にそのテーブルのデータが変更されないようにしたいのですが。
より高いトランザクション分離レベルの1つを使用する必要があります。 REPEATABLE READは、読み取ったデータが変更されないようにします。 SERIALIZABLEは、読み取ったデータが変更されないようにします 挿入されていない新しいデータ。クエリヒントを使用するのではなく、トランザクション分離レベルを使用するのが正しいアプローチです。ケンドラリトルには、隔離レベルを説明する素敵なポスターがあります。