8

मैं एक संग्रहीत प्रक्रिया है कि एक TableA करने के लिए TableB के शामिल होने के प्रदर्शन करती है:एसक्यूएल सर्वर डेडलॉक फिक्स: ऑर्डर में शामिल हों, या स्वचालित रूप से पुनः प्रयास करें?

SELECT <--- Nested <--- TableA 
      Loop <-- 
         | 
         ---TableB 

इसी समय, एक सौदे में, पंक्तियों TableB में TableA में डाला जाता है, और उसके बाद।

यह स्थिति कभी कभी गतिरोध, संग्रहीत प्रक्रिया के रूप में TableB से, खड़ी कर रहा है का चयन पकड़ लेता पंक्तियों जबकि डालने TableA की जाने वाली पंक्तियां कहते हैं, और फिर एक दूसरे को तालिका जाने के लिए अन्य चाहता है:

जब तक यह मिलती है -
INSERT  SELECT 
========= ======== 
Lock A  Lock B 
Insert A Select B 
Want B  Want A 
....deadlock... 

तर्क जब मैं व्यक्तिगत रूप से जिस क्रम में एसक्यूएल सर्वर अपने में शामिल होने करता है परवाह नहीं है, बी को INSERT की आवश्यकता पहले एक को पंक्तियां जोड़ने के लिए, और उसके बाद।

डेडलॉक्स को ठीक करने की सामान्य सिफारिश यह सुनिश्चित करना है कि हर कोई उसी क्रम में संसाधनों तक पहुंच सके। लेकिन इस मामले में एसक्यूएल सर्वर का अनुकूलक मुझे बता रहा है कि विपरीत क्रम "बेहतर" है। मैं एक और शामिल होने के लिए मजबूर कर सकता हूं, और एक खराब प्रदर्शन क्वेरी है।

लेकिन क्या मुझे चाहिए?

क्या मुझे अब एक और ऑर्डर के साथ ऑप्टिमाइज़र को ओवरराइड करना चाहिए, जिसे मैं उपयोग करना चाहता हूं?

या मुझे सिर्फ त्रुटि मूल त्रुटि 1205, और चयन कथन पुनः सबमिट करें?

प्रश्न यह नहीं है कि जब मैं ऑप्टिमाइज़र को ओवरराइड करता हूं और इसके लिए कुछ गैर-इष्टतम करने के लिए क्वेरी कितनी खराब हो सकती है। सवाल यह है: क्या खराब प्रश्नों को चलाने के बजाए स्वचालित रूप से पुनः प्रयास करना बेहतर है?

उत्तर

9

क्या स्वचालित रूप से डेडलॉक्स को पुनः प्रयास करना बेहतर है। इसका कारण यह है कि आप को डेडलॉक को ठीक कर सकते हैं, केवल बाद में किसी अन्य को हिट करने के लिए। एसक्यूएल रिलीज के बीच व्यवहार बदल सकता है, यदि टेबल हार्डवेयर का आकार बदलता है, तो सर्वर हार्डवेयर विनिर्देश बदलते हैं, और सर्वर पर लोड भी बदल जाता है। यदि डेडलॉक लगातार होता है, तो आपको इसे खत्म करने के लिए सक्रिय कदम उठाने चाहिए (एक सूचकांक आमतौर पर उत्तर होता है), लेकिन दुर्लभ डेडलॉक्स के लिए (हर 10 मिनट या उससे भी कम कहें), एप्लिकेशन में पुनः प्रयास डेडलॉक को मास्क कर सकता है। आप पढ़ सकते हैं या लिखते हैं, क्योंकि लिखने के लिए, सभी लिखने के संचालन परमाणु रखने के लिए उचित शुरुआत लेनदेन/प्रतिबद्ध लेनदेन से घिरा हुआ है और इसलिए उन्हें समस्याएं पुनः प्राप्त करने में सक्षम हैं।

विचार करने का एक और तरीका read committed snapshot पर बदल रहा है। जब यह सक्षम होता है, तो चयन किसी भी ताले को नहीं लेगा, फिर भी लगातार पढ़ता है।

+0

रीमस, रीडिंग रीडिंग सही समझ में आता है, लेकिन डेडलॉक्स के बाद स्वचालित रूप से रीट्रीइंग लिखने के बाद खोए गए अपडेट की ओर जाता है। जब आप लिखते हैं और डेडलॉक पीड़ित बन जाते हैं, तो संभव है कि जिस डेटा को आप स्पर्श करने जा रहे हैं उसे किसी और द्वारा संशोधित किया गया है। हमें ऐसे मामलों में स्वचालित रूप से फिर से लिखना नहीं चाहिए। हमें संभावित रूप से संशोधित डेटा को फिर से पढ़ना चाहिए, और फिर से विचार करना चाहिए कि हम सहेजना चाहते हैं या नहीं। समझ में आता है? –

+1

@AlexKuznetsov: यह बेतुका है, यदि कोई लेनदेन ठीक से लिखा गया है (यानी परमाणु रूप से) तो फिर इसे पुनः प्रयास करने के परिणामस्वरूप खोए गए अपडेट में परिणाम हो सकता है? मैं यह +1 दे रहा हूं, यह निश्चित रूप से सही जवाब है। आप हर डेडलॉक को रोक नहीं सकते हैं, यह एसीआईडी ​​अर्थशास्त्र के साथ पृष्ठभूमि शोर का हिस्सा है। – Aaronaught

+0

@Alex, @Aaro: आप वास्तव में दोनों सही हैं। 'पुनः प्रयास' से मेरा मतलब है कि वास्तव में 'वर्तमान स्थिति पढ़ें, परिवर्तन लागू करें, नई स्थिति वापस लिखें'। स्वचालित प्रसंस्करण अनुप्रयोगों के लिए, यह पैटर्न प्राप्त करने के लिए एक बहुत ही आसान है। हालांकि, उपयोगकर्ता इंटरैक्टिव अनुप्रयोगों के लिए, यह कठिन हो सकता है और अक्सर उचित स्थिति को वर्तमान स्थिति को दोबारा पढ़कर 'लिखने' को धक्का देना और उसे उपयोगकर्ता को फिर से प्रदर्शित करना है, इसलिए वह पुष्टि कर सकता है कि लागू परिवर्तन नए राज्य/संदर्भ में समझ में आता है, और मुझे लगता है कि एलेक्स के मन में यही था। इसलिए सही कार्रवाई मामले से मामले पर निर्भर करती है। –

2

ट्रैपिंग और रीरिंगिंग काम कर सकते हैं, लेकिन क्या आप सुनिश्चित हैं कि चयन हमेशा डेडलॉक पीड़ित है? यदि सम्मिलन डेडलॉक पीड़ित है, तो आपको पुनः प्रयास करने के बारे में और अधिक सावधान रहना होगा।

इस मामले में सबसे आसान समाधान, मुझे लगता है कि, आपके चयन के लिए नोलोक या रीडुनकॉमेटेड (एक ही चीज़) है। लोगों के पास गंदे पढ़ने के बारे में उचित चिंताओं हैं, लेकिन हमने वर्षों से उच्च समेकन के लिए नोलोक को चलाया है और कभी भी कोई समस्या नहीं है।

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

+0

SQL सर्वर लेनदेन को कम से कम संसाधनों के साथ वापस ले जाता है। "डालने" शायद एक दर्जन आवेषण की एक ट्रांस्क्टेड श्रृंखला है। चयन एक अकेला चयन है (संग्रहीत प्रक्रिया में लपेटा गया है) –

+0

@ इयान बॉयड: एक 'चयन' कथन एक डेडलॉक स्थिति नहीं बना सकता है। आपको कम से कम दो बहु-कथन लेनदेन की आवश्यकता है। उन्हें दोनों को डीएमएल होने की आवश्यकता नहीं है, लेकिन वे दोनों एक दूसरे के संसाधनों पर ताले की प्रतीक्षा कर रहे हैं और इसका मतलब है कि उन्हें दोनों को कम से कम दो संसाधनों का उपयोग करना चाहिए। यदि यह वास्तव में केवल एक ही 'SELECT' कथन है, किसी भी बड़े लेनदेन में लपेटा नहीं गया है, तो यह वास्तविक डेडलॉक नहीं हो सकता है, यह केवल I/O सिस्टम को बनाए रखने के लिए संघर्ष कर रहा है या कुछ अन्य अजीब सर्वर समस्या हो सकती है। – Aaronaught

+0

@ हारून। एक एकल चयन ** ** किसी अन्य प्रक्रिया के साथ डेडलॉक का कारण बन सकता है (http://blogs.msdn.com/bartd/archive/2006/09/25/770928.aspx) –

5

डेडलॉक्स से बचने के लिए, सबसे आम सिफारिशों में से एक है "एक ही क्रम में ताले हासिल करने के लिए" या "उसी क्रम में एक्सेस ऑब्जेक्ट्स"। स्पष्ट रूप से यह सही समझ में आता है, लेकिन क्या यह हमेशा व्यवहार्य है? क्या यह हमेशा संभव है? जब मैं इस सलाह का पालन नहीं कर सकता तो मैं मामलों का सामना करता हूं।

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

यदि मैं एक तालिका में एकाधिक तालिकाओं या एकाधिक पंक्तियों को स्पर्श करने वाले आदेशों का उपयोग करता हूं, तो आम तौर पर मेरे पास कोई नियंत्रण नहीं होता है जिसमें ऑर्डर लॉक प्राप्त होते हैं, (मानते हैं कि मैं संकेतों का उपयोग नहीं कर रहा हूं)।

तो, कई मामलों में एक ही क्रम में ताले हासिल करने का प्रयास करने से सभी डेडलॉक्स को रोका नहीं जाता है। इसलिए, हमें किसी भी प्रकार की हैंडलिंग डेडलॉक्स की ज़रूरत है - हम यह नहीं मान सकते कि हम उन्हें सब खत्म कर सकते हैं। बेशक, हम सेवा ब्रोकर या sp_getapplock का उपयोग करके सभी पहुंच को क्रमबद्ध करते हैं।

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

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

उदाहरण के लिए, यदि उपयोगकर्ता ने एक सेव बटन दबाया और बचत लेनदेन को डेडलॉक पीड़ित के रूप में चुना गया था, तो डेडलॉक के बाद स्क्रीन पर डेटा को दोबारा प्रदर्शित करना एक अच्छा विचार हो सकता है।

+0

+1 यह इंटरैक्टिव अनुप्रयोगों में सच है: यदि कोई लेखन खराब हो गया है, तो यह बहुत संभावना है कि जिस राज्य को अपडेट किया जा रहा था * * बदल गया था, क्योंकि यह वास्तव में संसाधन था जिस पर डेडलॉक हुआ था। मेरा जवाब कतार प्रसंस्करण में मेरी पृष्ठभूमि से प्रभावित था, जहां लेनदेन में 'उच्च स्तर' निहित है जो वापस रोल करता है। –

+0

@AlexKuznetsov: मैं एक अद्यतन पुनः प्रयास करने के खतरे के बारे में इतना सहमत नहीं हूं। यदि उपयोगकर्ता जल्द से जल्द 200ms बटन पर क्लिक करने के लिए हुआ, तो प्रभाव वही होगा। –

+0

यदि आपका एप्लिकेशन पहले से ही आशावादी समेकन का समर्थन करने के लिए डिज़ाइन किया गया है, तो यह एक डेडलॉक को एक संघर्ष के रूप में समझने के लिए समझ में आता है। यदि एप्लिकेशन वैसे भी परिवर्तनों को अधिलेखित कर देता है, तो आप अपडेट को पुनः प्रयास कर सकते हैं। – Aaronaught

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