What price a deadlock ?

“Oh, if we deadlock we’ll retry a few times until it goes through.”:

Ive had a few variations of this conversation of the years and on the face of it, what does it really matter ? You get a deadlock, you retry, retry, retry until eventually it does complete ok. You get the right data eventually and job done.

The problem here is that although SQLServer does a fine job of detecting and killing out one process or other that is involved in a deadlock, this is NOT instantaneous. There is a background process called the Lock Monitor that scans the lock chains for deadlocked processes. This job fires every 5 seconds. http://msdn.microsoft.com/en-us/library/ms178104(v=sql.105).aspx . The point being that in a deadlock scenario, it can be upto 5 seconds before a process is rolledback. 5 seconds is an eternity on a busy OLTP system.

Lets dummy up some code to demonstrate how with scale the situation gets worse and worse.

Create table DeadLockTab
(
ID integer identity Primary key,
SomeData uniqueidentifier
)
go
insert into DeadLockTab
(
    SomeData
)
Select top(10) newid()
from sys.columns
go

Now using Adam Machanics SQLQueryStress, lets run some code that will deadlock. All I wish to do I simply update 3 random rows in the 10 row table.

set nocount on
Declare @c integer =0

begin transaction
while(@C<3) begin
Declare @id integer = cast(rand()*10 as integer)+1
  Update DeadLockTab
     set SomeData = newid() 
  where ID = @id
select @c+=1

end
commit

 

Not the prettiest of code but it will do the job and if we run 100 iterations on 1 thread…

So, how about 100 iteration on 3 threads ?

A massive increase in the Seconds/Iteration from 0.0005 to 0.0900 ( well over a hundred times slower) and only with 6 deadlocks (Total Exceptions) over the 300 iterations.

Lets go crazy, and simulate a webscale 7 concurrent sessions J

That is the cost of a deadlock right there, an average of .1 second per call.

There are many solutions to this, but I want to say: don’t be afraid to proactively block. If we drop concurrency to 1 by using “Select count(*) from DeadlockTab with (TABLOCKX,HOLDLOCK)”

Then the average execution speed AT SCALE (and that’s what really matters) is dramatically improved.

So consider the time taken to resolve a deadlock next time you are told “If that happens we’ll simply resubmit the query”. 5 seconds is an eon and during this time further locks and blocks will accumulate behind the deadlocked processes further exacerbating the situation.

Leave a Reply

Your email address will not be published. Required fields are marked *