Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

SQL Transaction was deadlocked

Sometimes I get this kind of exception on not very busy SQL server:

Transaction (Process ID 57) was deadlocked on lock resources with another process and has been chosen as the deadlock victim. Rerun the transaction. Line number: 1 Error Number: 1205 Procedure:  Server name: P01 Error Source: .Net SqlClient Data Provider Error State: 47 

I'm not able to reproduce it. I tried to run several queries from different clients at the same time, but it didn't show up. What is the best way to handle this kind of issue when it happens inside procedure or inside trigger? I mean, how to rerun the transaction?

How to do it when exception occurs inside procedure called from the trigger, which was called by the insert made by some procedure (that is: procedure01 -> insert -> trigger -> procedure02 !)

like image 738
Piotr Salaciak Avatar asked Mar 22 '11 09:03

Piotr Salaciak


2 Answers

I would suggest that you come at the problem from two perspectives.

  1. Trap or Catch Deadlock Errors so that you can re-run the transaction that is chosen as the Deadlock Victim by the SQL Server database engine.

  2. Find out what is causing your Deadlock Events. You can do this in one of two ways, either run a SQL Server Profiler Trace to catch and record the Deadlock Event or you can enable some SQL Server Trace Flags that will record the details of the Deadlock Event to the SQL Server Error Log.

In the vast majority of cases, you can identify the cause of your Deadlock Events and remedy the situation through either a structural change in the database schema or a logical change to the code involved/responsible for the Deadlock Event.

For further reading take a look at:

  • How to track down Deadlocks Using SQL Server Profiler
  • Minimizing Deadlocks
  • Detecting and Ending Deadlocks

I hope I've answered your question but do let me know if I can help you further in any way.

like image 128
John Sansom Avatar answered Sep 21 '22 18:09

John Sansom


Set up a server-side SQL trace which captures deadlock graph events so you can look at the .trc file with SQL Profiler. This way you can have something in place to be able to troubleshoot any deadlock. I have provided the code below. You will have to change the file path as appropriate. It would be a good idea to configure this script to execute on SQL server startup.

FYI - A lot of different things can cause a deadlock, one of them being missing indexes.

declare @rc int declare @TraceID int declare @maxfilesize bigint set @maxfilesize = 10  declare @dtName nvarchar(50) select @dtName=(N'I:\Trace_Logs\DeadLockTrace'+ convert(nvarchar(8),getdate(),112))   -- Please replace the text InsertFileNameHere, with an appropriate -- filename prefixed by a path, e.g., c:\MyFolder\MyTrace. The .trc extension -- will be appended to the filename automatically. If you are writing from -- remote server to local drive, please use UNC path and make sure server has -- write access to your network share  exec @rc = sp_trace_create @TraceID output, 2, @dtName, @maxfilesize, NULL ,365  if (@rc != 0) goto error  -- Client side File and Table cannot be scripted  -- Set the events declare @on bit set @on = 1 exec sp_trace_setevent @TraceID, 148, 11, @on exec sp_trace_setevent @TraceID, 148, 51, @on exec sp_trace_setevent @TraceID, 148, 4, @on exec sp_trace_setevent @TraceID, 148, 12, @on exec sp_trace_setevent @TraceID, 148, 14, @on exec sp_trace_setevent @TraceID, 148, 26, @on exec sp_trace_setevent @TraceID, 148, 60, @on exec sp_trace_setevent @TraceID, 148, 64, @on exec sp_trace_setevent @TraceID, 148, 1, @on exec sp_trace_setevent @TraceID, 148, 41, @on exec sp_trace_setevent @TraceID, 25, 7, @on exec sp_trace_setevent @TraceID, 25, 15, @on exec sp_trace_setevent @TraceID, 25, 55, @on exec sp_trace_setevent @TraceID, 25, 8, @on exec sp_trace_setevent @TraceID, 25, 32, @on exec sp_trace_setevent @TraceID, 25, 56, @on exec sp_trace_setevent @TraceID, 25, 64, @on exec sp_trace_setevent @TraceID, 25, 1, @on exec sp_trace_setevent @TraceID, 25, 9, @on exec sp_trace_setevent @TraceID, 25, 25, @on exec sp_trace_setevent @TraceID, 25, 41, @on exec sp_trace_setevent @TraceID, 25, 49, @on exec sp_trace_setevent @TraceID, 25, 57, @on exec sp_trace_setevent @TraceID, 25, 2, @on exec sp_trace_setevent @TraceID, 25, 10, @on exec sp_trace_setevent @TraceID, 25, 26, @on exec sp_trace_setevent @TraceID, 25, 58, @on exec sp_trace_setevent @TraceID, 25, 3, @on exec sp_trace_setevent @TraceID, 25, 11, @on exec sp_trace_setevent @TraceID, 25, 35, @on exec sp_trace_setevent @TraceID, 25, 51, @on exec sp_trace_setevent @TraceID, 25, 4, @on exec sp_trace_setevent @TraceID, 25, 12, @on exec sp_trace_setevent @TraceID, 25, 52, @on exec sp_trace_setevent @TraceID, 25, 60, @on exec sp_trace_setevent @TraceID, 25, 13, @on exec sp_trace_setevent @TraceID, 25, 6, @on exec sp_trace_setevent @TraceID, 25, 14, @on exec sp_trace_setevent @TraceID, 25, 22, @on exec sp_trace_setevent @TraceID, 59, 55, @on exec sp_trace_setevent @TraceID, 59, 32, @on exec sp_trace_setevent @TraceID, 59, 56, @on exec sp_trace_setevent @TraceID, 59, 64, @on exec sp_trace_setevent @TraceID, 59, 1, @on exec sp_trace_setevent @TraceID, 59, 21, @on exec sp_trace_setevent @TraceID, 59, 25, @on exec sp_trace_setevent @TraceID, 59, 41, @on exec sp_trace_setevent @TraceID, 59, 49, @on exec sp_trace_setevent @TraceID, 59, 57, @on exec sp_trace_setevent @TraceID, 59, 2, @on exec sp_trace_setevent @TraceID, 59, 14, @on exec sp_trace_setevent @TraceID, 59, 22, @on exec sp_trace_setevent @TraceID, 59, 26, @on exec sp_trace_setevent @TraceID, 59, 58, @on exec sp_trace_setevent @TraceID, 59, 3, @on exec sp_trace_setevent @TraceID, 59, 35, @on exec sp_trace_setevent @TraceID, 59, 51, @on exec sp_trace_setevent @TraceID, 59, 4, @on exec sp_trace_setevent @TraceID, 59, 12, @on exec sp_trace_setevent @TraceID, 59, 52, @on exec sp_trace_setevent @TraceID, 59, 60, @on  -- Set the Filters declare @intfilter int declare @bigintfilter bigint  -- Set the trace status to start exec sp_trace_setstatus @TraceID, 1  -- display trace id for future references select TraceID=@TraceID goto finish  error:  select ErrorCode=@rc  finish:  go 
like image 45
Quantum Elf Avatar answered Sep 24 '22 18:09

Quantum Elf