私のチームと私には、他のプロセスをブロックしているプロセスを特定して強制終了できるようにする必要があるという問題があります。これらのアクションを実行するために無料で利用できる大量のスクリプトがあります。私たちはさまざまなものを試し、コードを精査しました。 (あなたがこれらのクエリのいずれかを投稿した人なら、ありがとう!)
先に進む前に、これは変更できないベンダーアプリケーションに対するものであることをお伝えします。ベンダーは、プロセスがブロックされている理由を解明するために時間を費やすことも望んでいません。この時点での唯一の選択肢は、(ベンダーサポートによって提案されているように)長時間実行されているプロセスを強制終了することです。これらのプロセスを強制終了する前に、実行中のクエリを確認しますが、99.9%の時間でFETCH API_CURSOR00000000000A7E1F
と表示され、何も通知されません。
これまでのところ、これは手動プロセスでした。ここで、誰かが手動でプロセスを強制終了するのではなく、これらの長時間実行されているブロッキングプロセスの強制終了を自動化したいと思います。
このスクリプトを運用環境に配置する前にテストしたいと思います。意図的にブロッキングプロセスを作成するスクリプトの作成を手伝ってください。このアプリケーションでTEST環境を試しましたが、残念ながら、ブロッキングプロセスを複製することができませんでした。
よろしくお願いいたします。
BEGIN TRANSACTION
SELECT * FROM YourTable WITH (TABLOCKX, HOLDLOCK)
WAITFOR DELAY '00:05:00' -- 5 minutes
ROLLBACK TRANSACTION
そして、別のクエリウィンドウで:
SELECT * FROM YourTable
これはとても簡単です。 Management Studioで2つのクエリウィンドウを開きます。
最初のコードで次のようなものを実行します(誰も使用していないテストテーブルを選択します。これにより、テストテーブルがブロックされ、少なくとも1つの行があることを確認します)。
BEGIN TRANSACTION
SELECT * FROM sometesttable WITH (TABLOCK, XLOCK, HOLDLOCK)
次に、2番目のクエリウィンドウで:
SELECT * FROM sometesttable
2番目のクエリは、最初のクエリがコミットまたはロールバックされるまでブロックされます。
いくつかの同時セッションでこれを起動することもできます。
排他ロックを取得できるのは、一度に1つのセッションだけです。
BEGIN TRANSACTION;
EXEC sp_getapplock @Resource = 'FooBar',
@LockMode = 'Exclusive';
WAITFOR DELAY '00:00:30';
EXEC sp_releaseapplock @Resource = 'FooBar';
COMMIT TRANSACTION;