2010-06-24 11 views
5

मेरे पास SQL ​​सर्वर 2005 पर चल रहे अलग-अलग धागे में चलने वाली दो संग्रहीत प्रक्रियाएं हैं। एक प्रक्रिया तालिकाओं के एक सेट में नई पंक्तियां डालती है और दूसरी प्रक्रिया तालिका के उसी सेट से पुराने डेटा को हटा देती है। ये प्रक्रियाएं डीएलईवेल और मॉडल पर डेडलॉक में चल रही हैं। यहाँ स्कीमा है:मैं इन दो एसक्यूएल स्टेटमेंट्स के बीच डेडलॉक से कैसे बच सकता हूं?

Scrollbar Image http://www.barramsoft.com/pub/images/DeadLock2.jpg

टेबल DFile: प्राथमिक कुंजी = DFileID
टेबल DLevel: प्राथमिक कुंजी = DLevelID, विदेश कुंजी: DFileID
टेबल मॉडल: प्राथमिक कुंजी = मॉडलआईडी, विदेशी कुंजी: DFileID
तालिका ईमेंट: प्राथमिक कुंजी = एलिमेंट आईडी, विदेशी कुंजी 1: डीफाइलआईडी, विदेशी कुंजी 2:

मैं सटीक दो SQL कथन (प्रत्येक संग्रहीत प्रक्रिया से एक) है कि गतिरोध उत्पन्न कर रहे हैं अलग-थलग पड़ गए हैं DLevelID। मैंने प्रक्रियाओं में से किसी एक द्वारा रिपोर्ट की गई डेडलॉक देखी है। मैं दोनों मामलों में शीर्ष (1000) का उपयोग करता हूं और दोनों कथन एक लूप में निष्पादित किए जाते हैं जब तक वे हटाने/डालने के लिए छोड़ी गई पंक्तियों के साथ पूरा नहीं हो जाते।

एसक्यूएल वक्तव्य 1:

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

एसक्यूएल वक्तव्य 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 

नोट: @ fileID2@ fileID1 और के लिए मूल्यों को हमेशा अलग होने की गारंटी दी जाती है । डीएलवेल टेबल लगभग औसतन है। एक DFileID के लिए 60 पंक्तियां और इस प्रकार एक ही पास में सभी पंक्तियों को हटाने को पूरा कर दिया जाएगा।

मैं इन दो SQL कथनों के बीच एक डेडलॉक से कैसे बच सकता हूं?

संपादित करें 1: समस्या को बेहतर स्पष्ट करने के लिए पुनर्निर्मित; जोड़ा छवि; सरलीकृत एसक्यूएल और डीएलवेल टेबल में शामिल हो गए, जो डेडलॉक में योगदान नहीं दिया।

संपादित करें 2: डेडलॉक ग्राफ के एक्सएमएल जोड़ा गया।
डेडलॉक अब मॉडल तालिका पर होता है। मॉडल के लिए DLevel तालिका के लिए इसी तरह के डिलीवरी कथन और स्कीमा।

<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> 
+0

SQL सर्वर का कौन सा संस्करण? मुझे यकीन है कि यह एसक्यूएल 2000 में है !! –

+0

क्या डीएलवेल और एलिमेंट के बीच कोई विदेशी कुंजी बाधाएं हैं? –

+0

टूटी हुई लिंक: संस्करण SQL सर्वर 2005 एक्सप्रेस है। – Elan

उत्तर

0

मुझे संदेह है कि एक ही समय में हटाने और डालने के साथ किसी प्रकार का महत्वपूर्ण उल्लंघन होना चाहिए ..?

1

एक संभावित परिदृश्य: एक कनेक्शन एलिमेंट में एक पंक्ति डालें, और वह पंक्ति डीएलवेल में एक पंक्ति को संदर्भित करती है, और डीएलवेल में वह पंक्ति किसी अन्य कनेक्शन द्वारा हटा दी जा रही है। आपका नोलॉक संकेत विदेशी कुंजी पर लागू नहीं होता है।

+0

ये कथन अलग कनेक्शन में निष्पादित किए जाते हैं। डालने और हटाए गए बयानों द्वारा संदर्भित पंक्तियों (डीलीवेल तालिका का) हमेशा अलग होता है क्योंकि डीएफआईएलआईडी दोनों के बीच अलग होता है। यदि नोलॉक विदेशी कुंजी पर लागू नहीं होता है, तो हो सकता है कि दो कथन पेज लॉकिंग टकराव में चल रहे हों। मुझे पंक्ति और पेज लॉकिंग बंद करने के बारे में पता है, लेकिन क्या पंक्ति स्तर लॉकिंग को मजबूर करने का कोई तरीका है? – Elan

+0

"एलिमेंट में डालें ..." क्वेरी में DLevel तालिका में शामिल हो गए। अभी भी डेडलॉक प्राप्त करें। – Elan

1

आप एलिमेंट टेबल से DLEvel.DFileID को विदेशी कुंजी को हटाने का प्रयास कर सकते हैं। चूंकि आपके पास DLevel.DlevelID पर प्राथमिक कुंजी है और आप एलिमेंट में एक विदेशी कुंजी के रूप में संदर्भित करते हैं, तो DFileID विदेशी कुंजी की वास्तव में आवश्यकता नहीं है।

संबंधित मुद्दे