テーブルからすべてのレコードを読み取り、それらをすべて削除することになっている単純な SQL コマンドがあります。正確な瞬間に他の誰かがこのテーブルに書き込みを行っている可能性があるため、テーブルをロックして、削除したものすべてが読み取り済みのものであることを確認したいと考えています。
BEGIN TRAN T1;
SELECT LotID FROM fsScannerIOInvalidCachedLots WITH (TABLOCK, HOLDLOCK);
DELETE FROM fsInvalidCachedLots;
COMMIT TRAN T1;
本当に奇妙なことは、これが動作するように使用されていることです。テストを通じてしばらくは機能しましたが、すべてを読み込んでいるため、何かが変わったと思いますが、レコードは削除されていません。その結果、SQL Server の CPU 使用率が高くなります。これは、次に実行するときに実行にかなりの時間がかかるためです。これは、ロックに関係していると思われます。
ここで何が起こっているのでしょうか?私は両方を試しましTABLOCK
たTABLOCKX
更新: そうそう、言い忘れたことですが、プログラムが次に読み取りを行うまで、そのテーブルを照会することはできません。つまり、そのステートメントがコードで実行された後 (コマンドと接続が破棄された後)、Management Studio 内からそのテーブルをクエリしようとすると、ハングするだけです。これは、まだロックされていることを意味すると思います。しかし、次のデータベース接続に到達するまで呼び出しプログラムをステップ実行すると、最初の読み取りの直後にテーブルがロックされなくなります。