2010-05-31 17 views
5

क्यों हैं, मुझे अपने बड़े वेब एप्लिकेशन में बहुत सारे डेडलॉक्स मिल रहे हैं।मेरे पास डेडलॉक्स के बारे में डेटा है, लेकिन मुझे समझ में नहीं आता कि वे

How to automatically re-run deadlocked transaction? (ASP.NET MVC/SQL Server)

यहाँ मैं दोबारा चला गतिरोध लेनदेन करना चाहता था, लेकिन मैं गतिरोध से छुटकारा पाने के लिए कहा गया था - यह बहुत बेहतर है, गतिरोध पकड़ने की कोशिश कर की तुलना में।

इसलिए मैंने पूरे दिन एसक्यूएल प्रोफाइलर के साथ बिताया, ट्रेसिंग कुंजी आदि सेट किया और यह मुझे मिला।

Users तालिका है। मैं निम्न क्वेरी के साथ एक बहुत ही उच्च प्रयोग करने योग्य पृष्ठ है (यह केवल क्वेरी नहीं है, लेकिन यह एक है कि मुसीबतों का कारण बनता है है)

UPDATE Users 
SET views = views + 1 
WHERE ID IN (SELECT AuthorID FROM Articles WHERE ArticleID = @ArticleID) 

और फिर वहाँ में निम्न क्वेरी सभी पृष्ठों है:

User = DB.Users.SingleOrDefault(u => u.Password == password && u.Name == username); 

वहीं मैं कुकीज़ से उपयोगकर्ता प्राप्त करता हूं।

अक्सर एक डेडलॉक होता है और यह दूसरी लिंक-टू-एसक्यूएल क्वेरी पीड़ित के रूप में चुनी जाती है, इसलिए यह नहीं चलती है, और मेरी साइट के उपयोगकर्ता एक त्रुटि स्क्रीन देखते हैं।

यह .XDL ग्राफ एसक्यूएल प्रोफाइलर द्वारा कब्जा कर लिया से जानकारी है (यह है सिर्फ पहली गतिरोध, यह न केवल एक है पूरी सूची विशाल है।।):

<deadlock-list> 
    <deadlock victim="process824df048"> 
     <process-list> 
      <process id="process824df048" taskpriority="0" logused="0" waitresource="PAGE: 7:1:13921" waittime="1830" ownerId="91418" transactionname="SELECT" lasttranstarted="2010-05-31T12:17:37.663" XDES="0x868175e0" lockMode="S" schedulerid="2" kpid="5076" status="suspended" spid="72" sbid="0" ecid="2" priority="0" trancount="0" lastbatchstarted="2010-05-31T12:17:37.663" lastbatchcompleted="2010-05-31T12:17:37.663" clientapp=".Net SqlClient Data Provider" hostname="WIN-S41KV2CLS67" hostpid="6920" isolationlevel="read committed (2)" xactid="91418" currentdb="7" lockTimeout="4294967295" clientoption1="671088672" clientoption2="128056"> 
       <executionStack> 
        <frame procname="adhoc" line="1" stmtstart="74" sqlhandle="0x02000000de1cb30b5b2e40e31ffb345af3c7529430b559c2"> 
*password-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------  </frame> 
        <frame procname="unknown" line="1" sqlhandle="0x000000000000000000000000000000000000000000000000"> 
unknown  </frame> 
       </executionStack> 
       <inputbuf> 
       </inputbuf> 
      </process> 
      <process id="process8765fb88" taskpriority="0" logused="216" waitresource="PAGE: 7:1:14196" waittime="1822" ownerId="91408" transactionname="UPDATE" lasttranstarted="2010-05-31T12:17:37.640" XDES="0x86978e90" lockMode="IX" schedulerid="2" kpid="5216" status="suspended" spid="73" sbid="0" ecid="0" priority="0" trancount="2" lastbatchstarted="2010-05-31T12:17:37.557" lastbatchcompleted="2010-05-31T12:17:37.557" clientapp=".Net SqlClient Data Provider" hostname="WIN-S41KV2CLS67" hostpid="6920" loginname="sdfkj93jks9sl" isolationlevel="read committed (2)" xactid="91408" currentdb="7" lockTimeout="4294967295" clientoption1="671088672" clientoption2="128056"> 
       <executionStack> 
        <frame procname="database.dbo.UpdateUserStats" line="31" stmtstart="1794" stmtend="2088" sqlhandle="0x03000700bac8836333e58f00879d00000100000000000000"> 
UPDATE Users 
    SET Views = Views + 1 
    WHERE ID IN (SELECT AuthorID FROM Articles WHERE ArticleID = @ArticleID)  </frame> 
        <frame procname="adhoc" line="1" stmtstart="84" sqlhandle="0x01000700b7c78e0760dd3f81000000000000000000000000"> 
EXEC @RETURN_VALUE = [dbo].[UpdateUserStats] @UserID = @p0 </frame> 
        <frame procname="unknown" line="1" sqlhandle="0x000000000000000000000000000000000000000000000000"> 
unknown  </frame> 
       </executionStack> 
       <inputbuf> 
(@p0 int,@RETURN_VALUE int output)EXEC @RETURN_VALUE = [dbo].[UpdateUserStats] @UserID = @p0 </inputbuf> 
      </process> 
      <process id="process86ce0988" taskpriority="0" logused="10000" waittime="1806" schedulerid="1" kpid="2604" status="suspended" spid="72" sbid="0" ecid="0" priority="0" trancount="0" lastbatchstarted="2010-05-31T12:17:37.663" lastbatchcompleted="2010-05-31T12:17:37.663" clientapp=".Net SqlClient Data Provider" hostname="WIN-S41KV2CLS67" hostpid="6920" loginname="sdfkj93jks9sl" isolationlevel="read committed (2)" xactid="91418" currentdb="7" lockTimeout="4294967295" clientoption1="671088672" clientoption2="128056"> 
       <executionStack> 
        <frame procname="adhoc" line="1" stmtstart="74" sqlhandle="0x02000000de1cb30b5b2e40e31ffb345af3c7529430b559c2"> 
*password-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------  </frame> 
        <frame procname="unknown" line="1" sqlhandle="0x000000000000000000000000000000000000000000000000"> 
unknown  </frame> 
       </executionStack> 
       <inputbuf> 
*password-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- </inputbuf> 
      </process> 
     </process-list> 
     <resource-list> 
      <pagelock fileid="1" pageid="13921" dbid="7" objectname="database.dbo.Users" id="lock85535c80" mode="IX" associatedObjectId="72057594046382080"> 
       <owner-list> 
        <owner id="process8765fb88" mode="IX"/> 
       </owner-list> 
       <waiter-list> 
        <waiter id="process824df048" mode="S" requestType="wait"/> 
       </waiter-list> 
      </pagelock> 
      <pagelock fileid="1" pageid="14196" dbid="7" objectname="database.dbo.Users" id="lock8469f980" mode="SIU" associatedObjectId="72057594046382080"> 
       <owner-list> 
        <owner id="process86ce0988" mode="S"/> 
       </owner-list> 
       <waiter-list> 
        <waiter id="process8765fb88" mode="IX" requestType="convert"/> 
       </waiter-list> 
      </pagelock> 
      <exchangeEvent id="Pipe894b0680" WaitType="e_waitPipeGetRow" nodeId="0"> 
       <owner-list> 
        <owner id="process824df048"/> 
       </owner-list> 
       <waiter-list> 
        <waiter id="process86ce0988"/> 
       </waiter-list> 
      </exchangeEvent> 
     </resource-list> 
    </deadlock> 

मैं गतिरोध के बारे में बहुत पढ़ा ... और मुझे समझ में नहीं आता कि यह एक डेडलॉक क्यों कर रहा है।

तो जाहिर है कि ये दोनों प्रश्न अक्सर चलते हैं। कम से कम एक बार एक बार। शायद और भी अक्सर (300-400 उपयोगकर्ता ऑनलाइन)। तो वे एक ही समय में बहुत आसानी से चल सकते हैं, लेकिन यह एक डेडलॉक क्यों करता है? कृपया मदद करे।

धन्यवाद

+1

क्या आप SQL2005 या बाद में हैं? यदि आपको एसक्यूएल प्रोफाइलर से डेडलॉक ग्राफ मिल गया है? क्या आपको पता है कि लेनदेन अलगाव स्तर आपके प्रश्नों के तहत क्या चल रहा है? –

+0

हां मुझे ग्राफ मिला। यही वह जगह है जहां से मुझे यह जानकारी मिली। मैं लेनदेन अलगाव के बारे में कुछ भी नहीं जानता।मैं इसे कहां देख सकता हूं? – Alex

+1

प्रोफाइलर ट्रेस में सीधे डेडलॉक ग्राफ़ ईवेंट पर क्लिक करें और ईवेंट डेटा निकालें चुनें, इसे xml के रूप में सहेजें। फिर इसे नोटपैड में खोलें और "अलगावलेवल" ढूंढें –

उत्तर

11

आपको डेडलॉक ग्राफ़ को कैप्चर करने की आवश्यकता है। प्रोफाइलर संलग्न करें और Deadlock Graph Event कक्षा को कैप्चर करें। .XDL ग्राफ़ को सहेजें और उस जानकारी को अपनी पोस्ट में जोड़ें।

तब तक, यह स्पष्ट है कि आपके डीबी.उसर।

CREATE INDEX idxUsersNamePassword on Users(Name,Password); 

मैं उम्मीद उपयोगकर्ता पहले से ही आईडी पर एक सूचकांक है, और लेख जो AuthorID भी शामिल किया गया है ArticleID पर एक सूचकांक है: SingleOrDefault क्वेरी कम से कम, नाम और पासवर्ड पर नहीं तो नाम पर एक सूचकांक की आवश्यकता है। उपयोगकर्ताओं को मानना। आईडी और लेख। आर्टिकलआईडी पीके हैं, वे संबंधित टेबल हैं, वे शायद संबंधित की क्लस्टर कुंजी हैं इसलिए यह सच है। हालांकि, डबल चेकिंग के लायक है।

और, जैसा कि मैं पहले से ही आप अपने पिछले पोस्ट में एक बार जवाब आप आगे बढ़ने और छोड़ने के लिए संयुक्त राष्ट्र-जवाब का फैसला किया है, तो आप Snapshot Isolation चालू करने पर विचार करना चाहिए: भंडारण स्पष्ट पाठ में पासवर्ड है

ALTER DATABASE ... SET READ_COMMITTED_SNAPSHOT ON 

कि इसके अलावा, एक प्रमुख # फ़ेल।

तीन प्रक्रियाओं (अनुरोध) कर रहे हैं गतिरोध की जानकारी के बाद अद्यतन:

  • ए) ... F048 जो SELECT ... FROM Users WHERE Password = ... and Name = ...
  • बी चल रहा है) ... 0988 है जो SELECT ... FROM Users WHERE Password = ... and Name = ...
  • सी) ... FB88 जो UPDATE ...
0 चला रहा है

गतिरोध चक्र है:

  1. सी पर पृष्ठ नौवीं ताला इंतजार कर रहा है, अवरुद्ध है द्वारा एक के एस ताला पर पृष्ठ एस ताला
  2. बी प्रतीक्षा करता है, सी नौवीं ताला द्वारा अवरुद्ध है
  3. एक समानांतर पर इंतजार कर रहा है एक्सचेंज संसाधन, बी

इसलिए चक्र सी-> ए-> बी-> सी है।

इस तथ्य से कि दो चयन शामिल हैं, एक समानांतर योजना का उपयोग करें और 2) पृष्ठ ताले का उपयोग स्पष्ट है कि वे संपूर्ण उपयोगकर्ता तालिका का अंत-अंत-अंत स्कैन करते हैं। तो समस्या यह है कि, जैसा कि मैंने भविष्यवाणी की थी, उपयोगकर्ताओं पर (नाम, पासवर्ड) पर इंडेक्स की कमी जो क्वेरी को बहुत अधिक डेटा स्कैन करने का कारण बनती है। इंडेक्स जोड़ना एनसी इंडेक्स पर सीधे सीईईके में और क्लस्टर्ड इंडेक्स पर एक लुकअप को बदल देगा, और यह अद्यतन के साथ ओवरलैप की खिड़की को नाटकीय रूप से कम करेगा। अभी अपडेट सभी से संघर्ष के लिए बहुत अधिक गारंटी है, क्योंकि प्रत्येक चयन को प्रत्येक पंक्ति को पढ़ने की गारंटी दी जाती है।

सूचकांक जोड़ना तत्काल समस्या को कम करेगा। स्नैपशॉट अलगाव का उपयोग मास्क समस्या होगी, क्योंकि एंड-टू-एंड स्कैन अभी भी तब तक होने जा रहे हैं जब तक कि (नाम, पासवर्ड) अनुक्रमणिका नहीं जोड़ा जाता है। या केवल (नाम) भी काम करेगा।

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

+1

क्षमा करें, मैं आपका जवाब स्वीकार करना भूल गया। हां, मैं पासवर्ड भंडारण प्रणाली को अद्यतन करने जा रहा हूं। मैं अपने प्रश्न को .XDL जानकारी के साथ अपडेट कर दूंगा। – Alex

+0

.XDL जानकारी पोस्ट की गई है। – Alex

+0

इस तरह के एक विस्तृत उत्तर के लिए बहुत बहुत धन्यवाद! मैं प्राथमिक कुंजी से अलग किसी अन्य कॉलम को अनुक्रमणित करने में कभी नहीं आया। (नाम, पासवर्ड) इंडेक्स जोड़ने के लिए मुझे क्या करने की ज़रूरत है? मुझे तालिका के डिजाइनर में इंडेक्स/कुंजी विंडो मिली। इसमें एक PK_Users कुंजी है, और मैं उपयोगकर्ता नाम के लिए IX_Users कुंजी जोड़ सकता हूं, लेकिन मैं इसे पासवर्ड से कैसे जोड़ सकता हूं? फिर से धन्यवाद। – Alex

1

आपका समस्या है जो यहां Diagnosing Deadlocks in SQL Server 2005

के साथ-साथ एक बहुत की है (LINQ एसक्यूएल के लिए, केवल लेन-देन पढ़ें एक पढ़ें लिखें लेन-देन से गतिरोध जा रहा है)

आप SQL2005 पर हैं या बाद में शायद उस थ्रेड पर चर्चा के रूप में स्नैपशॉट अलगाव स्थापित करना नौकरी करेगा। अन्यथा आप जिस संस्करण का उपयोग कर रहे हैं उसके विवरण के साथ अपनी पोस्ट अपडेट करें।

+0

धन्यवाद, मुझे एक नज़र आएगी। – Alex

1

इस स्थिति में (यानी आप जिस डेटा को पढ़ रहे हैं और उस डेटा पर होने वाले अपडेट की प्रकृति) मैं उपयोगकर्ता लुकअप क्वेरी को असामान्य अलगाव पढ़ने पर चलाऊंगा।

वैकल्पिक रूप से, एक और अधिक शामिल परिवर्तन। आपके द्वारा पोस्ट किए गए विवरण से, मैं उपयोगकर्ता रिकॉर्ड पर विचारों को बनाए रखने पर विचार नहीं करता। मैं इसके बजाय अनुच्छेद के विरुद्ध व्यूकाउंट रिकॉर्ड करूंगा, फिर किसी उपयोगकर्ता के लेखों के योग से कुल दृश्यों को घबराऊंगा। AuthorID द्वारा दृश्य देखें।

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