क्या नेटवर्क को डिस्कनेक्ट करने से कोई क्वेरी बंद हो जाती है?


13

मैंने हाल ही में 100,000 रिकॉर्ड के खिलाफ एक अपडेट क्वेरी निष्पादित की है। मुझे एहसास हुआ कि जब क्वेरी चल रही थी और नेटवर्क केबल को जल्दी से अनप्लग कर दिया था, तो मैंने एक गलती की।

अद्यतन क्वेरी करता है

  1. प्रसंस्करण बंद करो और पूरी तरह से रोलबैक?
  2. पूरा करने और प्रतिबद्ध करने के लिए प्रसंस्करण जारी रखें?
  3. प्रसंस्करण को रोकें और लक्षित पंक्तियों के केवल भाग को अद्यतन करें?

2
एक बार जब कोई क्वेरी सर्वर से टकराती है तो यह तब तक जारी रहेगी जब तक आप सर्वर पर क्वेरी रद्द नहीं कर देते।
जेपी चौहान


1
मार्टिन की टिप्पणी आपके सवाल का सीधा जवाब देती है, रोबोकॉप। यदि आपकी क्वेरी चलने से पहले नेटवर्क डिस्कनेक्ट के SQL सर्वर को सूचित करता है , तो SQL सर्वर इसे वापस रोल करेगा। अन्यथा, यदि SQL सर्वर से पहले क्वेरी पूरी हो जाती है तो नेटवर्क डिस्कनेक्ट हो गया था, तो वह प्रतिबद्ध होगा। किसी भी स्थिति में (यह मानकर कि आपने एकल अद्यतन क्वेरी लिखी है) SQL सर्वर आंशिक अद्यतन निष्पादित करेगा।
निक चामास

जवाबों:


22

जैसा कि निक और मार्टिन द्वारा उल्लेख किया गया है, आपकी क्वेरी की अंतिम स्थिति इस बात पर निर्भर करती है कि क्वेरी पूरा होने से पहले SQL सर्वर आपके नेटवर्क केबल पुल के बारे में जानता है या नहीं। ऑनलाइन पुस्तकों से (हालांकि मुझे यह दिलचस्प लगता है कि 2000 , 2005 , 2008 और 2008 R2 में इसके लिए समतुल्य विषय हैं , लेकिन 2012 या 2014 नहीं):

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

(एक तरफ के रूप में, दूसरे अंतिम वाक्य में शब्द कनेक्शन शायद लेन-देन होने के लिए था । मुझे नहीं पता कि कोई कनेक्शन वापस कैसे लेता है।)

इसी तरह से, SQL सर्वर अनपेक्षित रूप से बंद होने के बाद रिकवरी के दौरान लेनदेन को पूर्ववत या फिर से कर सकता है, और यह शटडाउन के समय लेनदेन की स्थिति पर निर्भर करेगा। मैंने देखा है कि लोग इस रणनीति का उपयोग करने के लिए प्राप्त कर रहे हैं कि आप क्या करने की कोशिश कर रहे थे (लेनदेन को रद्द करें) और जब सर्वर ने फिर से काम शुरू किया तो बस फिर से किया गया था (इसलिए उनके घुटने-झटका की प्रतिक्रिया का शुद्ध प्रभाव बहुत करीब था शून्य से वे अपेक्षित)।

तो इस के अधीन होने के बजाय, एक घबराहट में कठोर चीजें करने के बजाय, जैसे कि एक नेटवर्क केबल या मशीन को बंद करना, मैं सुझाव देता हूं कि भविष्य में आपके पास महत्वपूर्ण प्रणालियों के खिलाफ तदर्थ प्रश्नों को चलाने के बारे में बेहतर अनुशासन है। उदाहरण के लिए, इसके बजाय:

UPDATE dbo.sometable 
-- where *oops* I forgot this part

ये लो:

BEGIN TRANSACTION;

UPDATE dbo.sometable
-- where *oops* I forgot this part

-- COMMIT TRANSACTION;
-- ROLLBACK TRANSACTION;

फिर, यदि अपडेट वास्तव में सही था, तो आप COMMITभाग को हाइलाइट कर सकते हैं और इसे चला सकते हैं। यदि ऐसा नहीं था, तो आप शांति से उस ROLLBACKहिस्से को उजागर कर सकते हैं और उसे चला सकते हैं। आप उस बॉयलरप्लेट को शामिल करने के लिए अपने टेम्पलेट को संपादित करने के लिए SSMS टूल पैक जैसे ऐड-इन्स का भी उपयोग कर सकते हैं New Query

अब यह उस स्थिति में भी आपको परेशानी में डाल सकता है जब आप क्वेरी चलाते हैं और फिर या तो कमिट या रोलबैक नहीं करते हैं , क्योंकि अब आपका लेनदेन आपके उपयोगकर्ताओं को रोक रहा है। लेकिन यह बेहतर है तो अपरिवर्तनीय रूप से डेटा को संशोधित करना।

और निश्चित रूप से, हमेशा की तरह, एक बैकअप है जिस पर आप भरोसा कर सकते हैं।


5
यह उत्कृष्ट सलाह है और ओपी की समस्या की जड़ को संबोधित करता है, लेकिन यह वास्तव में इस सवाल का जवाब नहीं देता है कि क्वेरी जारी रही या नहीं।
निक चामास

3
धन्यवाद @ नहीं, मेरी प्रेरणा कारण को संबोधित करना था (जो कि प्रश्न को प्रभावित करता है), लक्षण नहीं, लेकिन मैंने अपना उत्तर अपडेट कर दिया है।
हारून बर्ट्रेंड

8

@ अरोन सही है। आपके आदेशों से पहले लेनदेन करना आपका सबसे अच्छा दांव है। यदि आप ऐसा करने के लिए याद नहीं कर सकते हैं, तो एक विकल्प Tools-Optionsसेटिंग में जाना और चालू करना है SET IMPLICIT_TRANSACTIONS। जैसे ही कुछ आदेश चलते हैं, यह स्वचालित रूप से लेनदेन शुरू कर देगा। इसमें शामिल हैं UPDATE, DELETEआदि यह किसी भी कमांड की एक पूरी तरह से पूरी सूची प्रतीत होती है जो "change"कुछ होगी । SELECTभी सूची में शामिल है और willएक लेनदेन शुरू करते हैं। आप आदेशों की एक पूरी सूची देख सकते हैं जो एक लेन-देन शुरू करते हैं यह यहां पर सेटिंग करेगा । यदि कोई पहले से ही चालू है तो यह लेनदेन नहीं करेगा। अब इसका नकारात्मक पक्ष यह है कि COMMITकिसी भी बदलाव के बाद आपको इसे याद रखना होगा ।

नोट: @ हारून के सुझाव के आधार पर मैं इस पर फिर से जोर देने जा रहा हूं।

This is very important!  You will have to remember to COMMIT after any change made!

मूल रूप से आप BEGINलेन-देन को भूलकर और किसी चीज़ को गड़बड़ करने के लिए बंद कर रहे हैं , COMMITएक लेनदेन को भूल जाने और इसे लटकाए रखने के लिए यदि आप इसे खुला छोड़ देते हैं और फिर दिन के लिए छोड़ देते हैं। मैंने सिर्फ एक क्वेरी विंडो को बंद करते हुए यह सोचकर परीक्षण किया कि यह मेरे लेन-देन को वापस ले लेगा, लेकिन अगर मैंने लेन-देन करना या रोलबैक करना चाहा तो इससे मुझे फायदा हुआ।

यहाँ छवि विवरण दर्ज करें


वास्तव में: एक लेनदेन शुरू SELECT करेगा (जो आपके द्वारा पोस्ट किए गए लिंक में भी प्रलेखित है)
a_horse_with_no_name

कि पकड़ने के लिए धन्यवाद @a_horse_with_no_name! मैंने ध्यान से नहीं पढ़ा और एक पुरानी याददाश्त से बाहर जा रहा था (यह स्पष्ट रूप से गलत था)।
केनेथ फिशर

1
यह एक सहायक पोस्ट है, लेकिन यह वास्तव में ओपी के सवाल का जवाब नहीं देता है कि क्या क्वेरी चलती रही या नहीं।
निक चामास

2
यह @ आरोन के उत्तर पर एक ऐड के रूप में था। यह सिर्फ एक टिप्पणी में डालने के लिए बहुत कुछ था।
केनेथ फिशर

2

मुझे लगता है कि यह वास्तव में निर्भर करता है:

यदि आप नेटवर्क केबल को अनप्लग करने से पहले कमांड पहले ही सर्वर तक पहुंच जाते हैं, तो कमांड अभी भी सामान्य रूप से निष्पादित करना जारी रखेगा।

यदि आपके पास सभी अपडेट कमांड को इनकैप्सुलेट करने के लिए एक TransactionScope (.Net में प्रयुक्त, अन्य भाषाओं के लिए निश्चित नहीं है), तो आप संभवतः लेनदेन को रोक सकते हैं यदि लेनदेन S.Sope.Complete () निष्पादित नहीं किया गया है, लेकिन कोई गारंटी नहीं है .. ।


2
आपने कहा था "यदि नेटवर्क केबल को अनप्लग करने से पहले कमांड पहले से ही सर्वर तक पहुंच जाता है, तो कमांड अभी भी सामान्य रूप से निष्पादित करना जारी रखेगा।" यह SQL सर्वर BOL पृष्ठ द्वारा विरोधाभास है कि मार्टिन ऊपर से जुड़ा हुआ है। "लेनदेन प्रसंस्करण के दौरान त्रुटियां" देखें ।
निक चामास

तुम सही हो। निर्दिष्ट लेनदेन के साथ, कमांड स्वचालित रूप से रोल-बैक होगी। लेकिन जैसा कि हमने अनुभव किया, जब कोई लेनदेन स्पष्ट रूप से निर्दिष्ट नहीं किया गया था, तो कमांड (एक बैच अपडेट बिना लेनदेन) को पूरी तरह से निष्पादित किया गया था, यहां तक ​​कि हमने अपने आवेदन को बीच में ही रोक दिया था, जो वास्तव में कनेक्शन तोड़ दिया था - लेकिन यह वास्तव में समय के रूप में एक अच्छा उदाहरण नहीं है शायद सही नहीं था। शायद इसके लिए कुछ परीक्षण करना अच्छा हो
Rex
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.