Sql-Server

死鎖——如何讓它變得更好?

  • August 1, 2017

我有這個查詢每隔一段時間就會死鎖。它正在對錶進行自我更新。(更新,來自)有沒有更好的方法來處理並發?這是計劃: https ://www.brentozar.com/pastetheplan/?id=r19CZMC8-

死鎖:UPDATE j SET StatusId=@StatusId – SELECT * FROM jobmanager.JobRun j with(rowlock) WHERE PrintBatchId=@PrintBatchI Proc

$$ Database Id = 11 Object Id = 191196327 $$

  1. 我會嘗試理解為什麼您的查詢會導致死鎖。查看死鎖圖資訊會很有用。嘗試啟用跟踪標誌(1204、1222)以從 SQL Server 日誌中獲取更多詳細資訊。
  2. 由於您使用的是行級鎖定並出現死鎖,我懷疑 PrintBatchId 可能有大量關聯的記錄。因此 SQL Server 必須將鎖升級到頁/表級別。結果,您會因更新不同的 PrintBatchId 而陷入僵局。(順便說一句。您在 PrintBatchId 上有索引嗎?沒有正確的索引行級別鎖定將不起作用)。嘗試使查詢過濾器更小。
  3. 如果您不能使過濾器更精確,我建議您擷取死鎖並重試更新嘗試。這是一個範常式式碼:
DECLARE @Retries INT = 5
   , @ErrorMessage nvarchar(max)
   , @ErrorLine INT    
   , @ErrorSeverity INT
   , @ErrorNumber INT 

WHILE (@Retries > 0)
BEGIN             
   BEGIN TRY
       --UPDATE Command.... 
       SELECT @retries = 0
   END TRY
   BEGIN CATCH
       SELECT 
             @ErrorMessage = ERROR_MESSAGE()
           , @ErrorLine    = ERROR_LINE()
           , @ErrorSeverity= ERROR_SEVERITY()
           , @ErrorNumber  = ERROR_NUMBER();

       IF (@ErrorNumber = 1205 AND @Retries > 0) -- If Deadlock, then retry 
           SELECT @ErrorMessage = 'Execution Failed due to a deadlock. Retrying... ';
       ELSE
       IF (@ErrorNumber = 1205 AND @Retries <= 0) -- If Deadlock, and max number of retries reached. Fail.
           SELECT @ErrorMessage = 'Execution Failed due to a deadlock after max number of retries ... ' + CHAR(13) + ' Original Error: Msg. ' + CAST(@ErrorNumber AS VARCHAR(MAX)) + ', ' + @ErrorMessage;
       ELSE
           SELECT @ErrorMessage = 'Execution Failed: Msg ' + CAST(@ErrorNumber AS VARCHAR(MAX)) + ', ' + @ErrorMessage;

       SELECT @Retries-=1;     

   END CATCH;
END

引用自:https://dba.stackexchange.com/questions/182378