私は比較的複雑なシステムを使用しています。静的テーブルは必要に応じて複数のデータソースから更新されます。データの動的な読み込みには4〜5秒かかり、結果をユーザーにすばやく表示するためです。
プロセス:
IF ( SELECT [LastStaticUpdateEvent] < [LastSaveEvent]
FROM [dbo].[Events]
WHERE [OrderNumber] = @OrderNumber
)
BEGIN
-- Update Static table
UPDATE [Static]
SET [Static].[A] = [App].[A]
,[Static].[B] = [App].[B]
FROM [dbo].[AppData] AS [App] -- View with many joins (4-5 secs)
INNER JOIN [dbo].[StaticResuts] AS [Static]
ON [Static].[OrderNumber] = [App].[OrderNumber]
WHERE [App].[OrderNumber] = @OrderNumber
-- Update Event Log
UPDATE [dbo].[Events]
SET [LastStaticUpdateVent] = SYSDATETIME()
WHERE [OrderNumber] = @OrderNumber
END
SELECT * FROM [dbo].[StaticResults]
問題は、このデータを同時に要求できることです。最初のUPDATEが完了する前に、ユーザーAとユーザーBの両方がdbo.Get_Dataを呼び出すと、デッドロックが発生します。
ルックアップを続行する前に、最初の呼び出しが完了するまで2番目の呼び出しを待機させる適切なメソッドまたはパターンはありますか?
ルックアップを続行する前に、最初の呼び出しが終了するまで2番目の呼び出しを待機させる適切なメソッドまたはパターンはありますか?
一度に1つのセッションでのみ実行できるコードブロックを作成する最も簡単な方法は、 アプリケーションロック を使用することです。 SQL Serverのロックエンジンを使用できますが、特定の行、ページ、またはテーブルをロックする代わりに、カスタム名でロックを作成します。例えば
begin transaction;
--begin exclusive section
exec sp_getapplock @Resource = 'Get_Data Exclusive Lock', @LockMode = 'Exclusive';
--do stuff in only one session
--end exclusive section
exec sp_releaseapplock @Resource = 'Get_Data Exclusive Lock';
commit transaction;