Sql-Server
死鎖——如何讓它變得更好?
我有這個查詢每隔一段時間就會死鎖。它正在對錶進行自我更新。(更新,來自)有沒有更好的方法來處理並發?這是計劃: 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 $$
- 我會嘗試理解為什麼您的查詢會導致死鎖。查看死鎖圖資訊會很有用。嘗試啟用跟踪標誌(1204、1222)以從 SQL Server 日誌中獲取更多詳細資訊。
- 由於您使用的是行級鎖定並出現死鎖,我懷疑 PrintBatchId 可能有大量關聯的記錄。因此 SQL Server 必須將鎖升級到頁/表級別。結果,您會因更新不同的 PrintBatchId 而陷入僵局。(順便說一句。您在 PrintBatchId 上有索引嗎?沒有正確的索引行級別鎖定將不起作用)。嘗試使查詢過濾器更小。
- 如果您不能使過濾器更精確,我建議您擷取死鎖並重試更新嘗試。這是一個範常式式碼:
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