मैं एक संग्रहीत प्रक्रिया है कि एक 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, और चयन कथन पुनः सबमिट करें?
प्रश्न यह नहीं है कि जब मैं ऑप्टिमाइज़र को ओवरराइड करता हूं और इसके लिए कुछ गैर-इष्टतम करने के लिए क्वेरी कितनी खराब हो सकती है। सवाल यह है: क्या खराब प्रश्नों को चलाने के बजाए स्वचालित रूप से पुनः प्रयास करना बेहतर है?
रीमस, रीडिंग रीडिंग सही समझ में आता है, लेकिन डेडलॉक्स के बाद स्वचालित रूप से रीट्रीइंग लिखने के बाद खोए गए अपडेट की ओर जाता है। जब आप लिखते हैं और डेडलॉक पीड़ित बन जाते हैं, तो संभव है कि जिस डेटा को आप स्पर्श करने जा रहे हैं उसे किसी और द्वारा संशोधित किया गया है। हमें ऐसे मामलों में स्वचालित रूप से फिर से लिखना नहीं चाहिए। हमें संभावित रूप से संशोधित डेटा को फिर से पढ़ना चाहिए, और फिर से विचार करना चाहिए कि हम सहेजना चाहते हैं या नहीं। समझ में आता है? –
@AlexKuznetsov: यह बेतुका है, यदि कोई लेनदेन ठीक से लिखा गया है (यानी परमाणु रूप से) तो फिर इसे पुनः प्रयास करने के परिणामस्वरूप खोए गए अपडेट में परिणाम हो सकता है? मैं यह +1 दे रहा हूं, यह निश्चित रूप से सही जवाब है। आप हर डेडलॉक को रोक नहीं सकते हैं, यह एसीआईडी अर्थशास्त्र के साथ पृष्ठभूमि शोर का हिस्सा है। – Aaronaught
@Alex, @Aaro: आप वास्तव में दोनों सही हैं। 'पुनः प्रयास' से मेरा मतलब है कि वास्तव में 'वर्तमान स्थिति पढ़ें, परिवर्तन लागू करें, नई स्थिति वापस लिखें'। स्वचालित प्रसंस्करण अनुप्रयोगों के लिए, यह पैटर्न प्राप्त करने के लिए एक बहुत ही आसान है। हालांकि, उपयोगकर्ता इंटरैक्टिव अनुप्रयोगों के लिए, यह कठिन हो सकता है और अक्सर उचित स्थिति को वर्तमान स्थिति को दोबारा पढ़कर 'लिखने' को धक्का देना और उसे उपयोगकर्ता को फिर से प्रदर्शित करना है, इसलिए वह पुष्टि कर सकता है कि लागू परिवर्तन नए राज्य/संदर्भ में समझ में आता है, और मुझे लगता है कि एलेक्स के मन में यही था। इसलिए सही कार्रवाई मामले से मामले पर निर्भर करती है। –