2017-06-14 13 views
0

これがSQLストアドプロシージャのデッドロックの良い例であると説明できますか?SQLデッドロックの例

BEGIN TRANSACTION MergeAccount 

MERGE INTO Name AS TARGET 
USING (
    SELECT @accountId, @playerName, @lastSeenDateTime 
) AS SOURCE (
    [AccountId], [Name], [LastSeenDateTime] 
) 
ON TARGET.[AccountId] = SOURCE.[AccountId] 
AND 
(
    SELECT TOP 1 [Name] 
    FROM [Name] 
    WHERE [AccountId] = @AccountId 
    ORDER BY [LastSeenDateTime] DESC 
) = SOURCE.[Name] 
WHEN NOT MATCHED BY TARGET THEN 
    INSERT (
     [AccountId], [Name], [LastSeenDateTime] 
    ) VALUES (
     [AccountId], [Name], [LastSeenDateTime] 
    ) 
WHEN MATCHED AND SOURCE.LastSeenDateTime > TARGET.LastSeenDateTime THEN 
    UPDATE 
    SET TARGET.LastSeenDateTime = SOURCE.LastSeenDateTime 
; 

COMMIT TRANSACTION MergeAccount 

たとえば、WHERE句でSELECT文をチェックすると、実際には同じユーザーの同じテーブルにデータを要求しています。

私はDECLAREを作成し、外部のvarにデータを受け入れ、where節を適用する必要がありますか?

このようにクエリを書くのは悪い習慣ですか?

+0

デッドロックは、* different *セッション間で発生し、1つのセッションの1つのステートメントでは発生しません。 (MERGEは本当にいくつかのこのようなバグを発見しています)あなたは実際にあなたが解決しようとしているデッドロックを持っていますか、これは仮説的な懸念ですか? –

+0

これはよく似たようなシナリオです:https://dba.stackexchange.com/questions/23467/merge-statement-deadlocking-itselfしかし、@ JeroenMostertごとに。これには、競合する第2セッションが必要です。 – JohnLBevan

+0

@ JeroenMostertこれは問題が発生しているため、有効な懸案事項です。プログラムは、このストアドプロシージャについて報告しています。非常に基本的なものでも、他のセッションと競合しています(同じアプリケーションの多くのボットを実行します)。既にかなりシンプルな方法でそれを単純化する方法はわかりません。 –

答えて

0

DeadLockシナリオ全体を分析し、それを再現したい場合は、

TSQL_LocksモデルでSQL Server Profilerを実行することをおすすめします。

デッドロックが発生した場合は、DeadLock graphの列に問題を分析するための素晴らしい方法があります。

関連する問題