How can I avoid a deadlock between these two SQL statements?

I have two stored procedures running on separate threads running on SQL Server 2005. One procedure inserts new rows into a set of tables, and the other procedure deletes old data from one set of tables. These procedures start at a standstill on the DLevel and Model tables. Here is the diagram:

Scrolling image http://www.barramsoft.com/pub/images/DeadLock2.jpg

DFile table: primary key = DFileID
DLevel table: primary key = DLevelID, foreign key: DFileID
Table Model : primary key = model identifier, foreign key: DFileID
ELement table: primary key = ElementID element, foreign key1: DFileID, foreign key2: DLevelID

I highlighted the exact two SQL statements (one from each stored procedure) that cause a dead end. I saw a dead end reported by any of the procedures. I use top (1000) in both cases, and both statements are executed in a loop until they contain the rows left to delete / insert.

SQL statement 1:

while (...) begin delete top (1000) from DLevel where DFileID = @fileID1 ... end 

SQL statement 2:

 while (...) begin insert into Element (ElementID, DFileID, LevelNum, ...) select top (1000) el.ElementID, el.DFileID, el.LevelNum, ... from ElementLoader el with (nolock) left outer join Element e with (nolock) on e.ElementID = el.ElementID where el.DFileID = @fileID2 and e.ElementID is null order by el.ElementID ... end 

Note. The values ​​for @ fileID1 and @ fileID2 are always guaranteed to be different. The DLevel table has an average of approx. 60 lines for a single DFileID and thus complete the deletion of all lines in a single pass.

How can I avoid a deadlock between these two SQL statements?

Edit 1: Rewritten to clarify the problem; added image; simplified SQL and a remote link to a DLevel table that did not contribute to a deadlock.

Edit 2: Added deadlock XML.
A dead end is now found on the model table. The same instruction and deletion scheme for the model as for the DLevel table.

 <deadlock victim="process2bae38"> <process-list> <process id="process2bae38" taskpriority="0" logused="4760" waitresource="PAGE: 11:1:1946" waittime="46" ownerId="4127445" transactionname="DELETE" lasttranstarted="2010-06-24T16:19:00.107" XDES="0xffffffff90552ae0" lockMode="S" schedulerid="1" kpid="14252" status="suspended" spid="58" sbid="0" ecid="0" priority="0" transcount="2" lastbatchstarted="2010-06-24T16:19:00.107" lastbatchcompleted="2010-06-24T16:19:00.107" clientapp=".Net SqlClient Data Provider" hostname="LT0103" hostpid="1668" loginname="NT AUTHORITY\SYSTEM" isolationlevel="read committed (2)" xactid="4127445" currentdb="11" lockTimeout="4294967295" clientoption1="673185824" clientoption2="128056"> <executionStack> <frame procname="CadExplorer5.dbo.pCleanUpOldFiles" line="364" stmtstart="23718" stmtend="23834" sqlhandle="0x03000b00fb1c2229b1a7f7009f9d00000100000000000000"> delete top (@batchSize) from Model where DFileID = @fileID </frame> </executionStack> <inputbuf> Proc [Database Id = 11 Object Id = 690101499] </inputbuf> </process> <process id="process2c95b8" taskpriority="0" logused="283388" waitresource="KEY: 11:72057594039304192 (8100bdf15e8b)" waittime="78" ownerId="4127412" transactionname="INSERT" lasttranstarted="2010-06-24T16:19:00.103" XDES="0xffffffff81d5ef18" lockMode="S" schedulerid="2" kpid="8460" status="suspended" spid="63" sbid="0" ecid="0" priority="0" transcount="2" lastbatchstarted="2010-06-24T16:18:59.413" lastbatchcompleted="2010-06-24T16:18:59.413" clientapp=".Net SqlClient Data Provider" hostname="LT0103" hostpid="1668" loginname="NT AUTHORITY\SYSTEM" isolationlevel="read committed (2)" xactid="4127412" currentdb="11" lockTimeout="4294967295" clientoption1="673185824" clientoption2="128056"> <executionStack> <frame procname="CadExplorer5.dbo.pLoadElements" line="288" stmtstart="28796" stmtend="33194" sqlhandle="0x03000b00a689fe2b2c5107019f9d00000100000000000000"> insert into Element ( ElementID, DFileID, ModelID, ElementTypeID, CADElementID, ParentID, LevelNum, Depth, NumChildren, Color, Weight, Style, Xlo, Ylo, Zlo, Xhi, Yhi, Zhi, Diagonal, XCenter, BitFlags, ElementModTime ) select top (@batchSize) el.ElementID, el.DFileID, el.ModelID, el.ElementTypeID, el.CADElementID, parent.ElementID as ParentID, (case when el.LoaderType = 1 and et.IsGraphical = 1 then el.LevelAttrib else null end) as LevelNum, --l.LevelNum, el.Depth, el.NumChildren, el.Color, el.Weight, el.Style, el.Xlo, el.Ylo, el.Zlo, el.Xhi, el.Yhi, el.Zhi, el.Diagonal, el.XCenter, </frame> </executionStack> <inputbuf> Proc [Database Id = 11 Object Id = 738101670] </inputbuf> </process> </process-list> <resource-list> <pagelock fileid="1" pageid="1946" dbid="11" objectname="CadExplorer5.dbo.Element" id="lockffffffff86ffd080" mode="IX" associatedObjectId="72057594039107584"> <owner-list> <owner id="process2c95b8" mode="IX"/> </owner-list> <waiter-list> <waiter id="process2bae38" mode="S" requestType="wait"/> </waiter-list> </pagelock> <keylock hobtid="72057594039304192" dbid="11" objectname="CadExplorer5.dbo.Model" indexname="PK_Model" id="lockffffffff8d66db80" mode="X" associatedObjectId="72057594039304192"> <owner-list> <owner id="process2bae38" mode="X"/> </owner-list> <waiter-list> <waiter id="process2c95b8" mode="S" requestType="wait"/> </waiter-list> </keylock> </resource-list> </deadlock> 
+5
sql deadlock nolock sql-server-2005-express
Jun 24 '10 at 18:09
source share
3 answers

One possible scenario: one connection inserts a line into the Element, and this line refers to a line in DLevel, and this line in DLevel is deleted by another connection. The nolock hint does not apply to foreign keys.

+1
Jun 24 '10 at
source share

You can try to remove the foreign key in DLevel.DFileID from the Element table. Since you have a primary key on DLevel.DlevelID, and you refer to it as a foreign key in Element, the DFileID foreign key is really not needed.

+1
Jun 25 2018-10-06T00:
source share

I suspect there must be some kind of key violation with deletion and insertion at the same time ..?

0
Jun 24 '10 at 18:28
source share



All Articles