Today I was approached by a developer whose app was deadlocking during testing. To emulate a user load he invoked a webservice in a loop with each loop having 10 invocations (each with different input parameters each time). The webservice called the sql backend (sql 2005). I have analyzed the deadlock (see bottom of this post) and wonder if you agree with my interpretation and can offer suggestions to minimize the chance of deadlocking. Here are my thoughts.
1. It appears that the processes ending “aeda8” and “452e8” are trying to delete a record from the same table. Each process is holding an exclusive lock on the same table which leads to a deadlock.
Note 1: I don’t understand why this leads to a deadlock. Why doesn’t the first process with the exclusive lock simply complete its task, release the lock, and let the other process have access to the table? That would seemingly avoid the deadlock
Note 2: despite each DELETE statement referencing the value “@myId” I believe those values are actually different, corresponding to different invocations of the web service.
2. I note the dev set the ISOLATION level to “Serializable”, the strictest level instead of using the default level “read committed”. (That could be part of the problem).
3. Instead of actually deleting records from the table perhaps an auxiliary table could be created with a bit column indicating if the record is regarded as being deleted.
4. I need to make sure the indexing on column “myID” is up-to-date!
Deadlock info follows.
TIA,
Edm2
--------------------------------------------------------------------------------------------------------
<deadlock-list>
<deadlock victim="process45452e8">
<process-list>
<process id="processbaeda8" taskpriority="0" logused="9576" waitresource="OBJECT: 26:2061875058:0 " waittime="4031" ownerId="869263486" transactionname="DeleteRecords"
lasttranstarted="2013-07-30T14:28:17.923" XDES="0x16567ede0" lockMode="X" schedulerid="1" kpid="12624" status="suspended" spid="111" sbid="2" ecid="0" priority="0"
transcount="2" lastbatchstarted="2013-07-30T14:28:17.923" lastbatchcompleted="2013-07-30T14:28:17.923" clientapp="EntityFramework" hostname="myHostname" hostpid="3624" loginname="myLogin"
isolationlevel="serializable (4)" xactid="869263486" currentdb="26" lockTimeout="4294967295" clientoption1="673185824" clientoption2="128056">
<executionStack>
<frame procname="myDB.dbo.DeleteRecords" line="23" stmtstart="1486" stmtend="1606" sqlhandle="0x0300220032a9dc3dacf61a01d2a100000100000000000000">
DELETE FROM dbo.myTable WHERE myID = @myID </frame>
</executionStack>
<inputbuf>
Proc [Database id="26" Object Id = 1037871410] </inputbuf>
</process>
<process id="process45452e8" taskpriority="0" logused="1768" waitresource="OBJECT: 26:2061875058:0 " waittime="4031" ownerId="869263480" transactionname="DeleteRecords"
lasttranstarted="2013-07-30T14:28:17.917" XDES="0xd0467040" lockMode="X" schedulerid="2" kpid="9492" status="suspended" spid="113" sbid="2" ecid="0" priority="0"
transcount="2" lastbatchstarted="2013-07-30T14:28:17.917" lastbatchcompleted="2013-07-30T14:28:17.917" clientapp="EntityFramework" hostname="myHostname" hostpid="3624" loginname="myLogin"
isolationlevel="serializable (4)" xactid="869263480" currentdb="26" lockTimeout="4294967295" clientoption1="673185824" clientoption2="128056">
<executionStack>
<frame procname="myDB.dbo.DeleteRecords" line="23" stmtstart="1486" stmtend="1606" sqlhandle="0x0300220032a9dc3dacf61a01d2a100000100000000000000">
DELETE FROM dbo.myTable WHERE myID = @myID </frame>
</executionStack>
<inputbuf>
Proc [Database id="26" Object Id = 1037871410] </inputbuf>
</process>
</process-list>
<resource-list>
<objectlock lockPartition="0" objid="2061875058" subresource="FULL" dbid="26" objectname="myDB.dbo.myTable" id="lock2b798b200" mode="IX" associatedObjectId="2061875058">
<owner-list>
<owner id="processbaeda8" mode="IX"/>
<owner id="process45452e8" mode="IX"/>
</owner-list>
<waiter-list>
<waiter id="process45452e8" mode="X" requestType="convert"/>
<waiter id="processbaeda8" mode="X" requestType="convert"/>
</waiter-list>
</objectlock>
</resource-list>
--- this looks like a second deadlock!
</deadlock>
<deadlock victim="processbaf2e8">
<process-list>
<process id="processbaf2e8" taskpriority="0" logused="0" waitresource="OBJECT: 26:2061875058:0 " waittime="4875" ownerId="869264641" transactionname="ParallelQueryXact"
lasttranstarted="2013-07-30T14:28:22.210" XDES="0x124417778" lockMode="S" schedulerid="1" kpid="7564" status="suspended" spid="53" sbid="2" ecid="0" priority="0"
transcount="1" lastbatchstarted="2013-07-30T14:28:21" lastbatchcompleted="2013-07-30T14:28:21" clientapp="EntityFramework" hostname="myHostname" hostpid="3624" loginname="myLogin" isolationlevel="serializable
(4)" xactid="869264635" currentdb="26" lockTimeout="4294967295" clientoption1="673185824" clientoption2="128056">
<executionStack>
<frame procname="myDB.dbo.GetValues" line="17" stmtstart="948" stmtend="1346" sqlhandle="0x03002200b2c5ee37e2579e00d3a100000100000000000000">
SELECT [COL1]
FROM dbo.myTable WHERE myID = @myID </frame>
</executionStack>
<inputbuf>
Proc [Database id="26" Object Id = 938395058] </inputbuf>
</process>
<process id="processbafd68" taskpriority="0" logused="1768" waitresource="OBJECT: 26:2061875058:0 " waittime="4875" ownerId="869263483" transactionname="DeleteRecords"
lasttranstarted="2013-07-30T14:28:17.920" XDES="0x1651430f0" lockMode="X" schedulerid="1" kpid="12912" status="suspended" spid="110" sbid="2" ecid="0" priority="0"
transcount="2" lastbatchstarted="2013-07-30T14:28:17.920" lastbatchcompleted="2013-07-30T14:28:17.920" clientapp="EntityFramework" hostname="myHostname" hostpid="3624" loginname="myLogin"
isolationlevel="serializable (4)" xactid="869263483" currentdb="26" lockTimeout="4294967295" clientoption1="673185824" clientoption2="128056">
<executionStack>
<frame procname="myDB.dbo.DeleteRecords" line="23" stmtstart="1486" stmtend="1606" sqlhandle="0x0300220032a9dc3dacf61a01d2a100000100000000000000">
DELETE FROM dbo.myTable WHERE myID = @myID </frame>
</executionStack>
<inputbuf>
Proc [Database id="26" Object Id = 1037871410] </inputbuf>
</process>
</process-list>
<resource-list>
<objectlock lockPartition="0" objid="2061875058" subresource="FULL" dbid="26" objectname="myDB.dbo.myTable" id="lock2b798b200" mode="IX" associatedObjectId="2061875058">
<owner-list>
<owner id="processbaf2e8" mode="Sch-S"/>
<owner id="processbaf2e8" mode="IS"/>
<owner id="processbafd68" mode="IX"/>
</owner-list>
<waiter-list>
<waiter id="processbaf2e8" mode="S" requestType="convert"/>
<waiter id="processbafd68" mode="X" requestType="convert"/>
</waiter-list>
</objectlock>
</resource-list>
</deadlock>
</deadlock-list>