2014-09-13 8 views
5

मेरे पास एक संग्रहीत प्रक्रिया है जो SQL सर्वर में एकाधिक तालिकाओं को अद्यतन कर रही है। इस प्रक्रिया का उपयोग सी # कोड से किया जा रहा है।क्या हमें सी # कोड और संग्रहीत प्रक्रिया दोनों में एसक्यूएल लेनदेन लागू करने की आवश्यकता है?

यदि मैं केवल सी # कोड में लेनदेन लागू करता हूं तो यह एक अच्छा अभ्यास होगा?

क्या मुझे सी # कोड और संग्रहीत प्रक्रिया दोनों में लेनदेन लागू करने की आवश्यकता है?

धन्यवाद

उत्तर

6

प्रक्रिया केवल एक ही SqlCommand में एक भी संग्रहीत प्रक्रिया बुला रहा है, तो बस संग्रहीत प्रक्रिया के अंदर लेनदेन को संभालने और सी # कोड से इसे प्रबंधित करने की कोई जरूरत नहीं है। एकाधिक SqlCommand निष्पादन में लेनदेन को बनाए रखने के लिए आपको केवल C# कोड में इसे प्रबंधित करने की आवश्यकता होगी।

FYI करें, दोनों परतों में लेन-देन के प्रबंध केवल तब आवश्यक है निम्न दोनों सत्य हैं:

  • सी # कोड बना रही है कई SqlCommand कॉल एक भी आपरेशन
  • संग्रहीत विचार करने की आवश्यकता है कि प्रक्रिया (ओं) को इस सी # कोड के बाहर से कॉल किया जा सकता है, जैसे अन्य संग्रहीत प्रक्रियाओं (जिस स्थिति में संग्रहीत प्रक्रियाओं को कॉल किया जाता है, उस समय मौजूदा लेनदेन नहीं हो सकता है।

ओ के बाहर उपर्युक्त परिदृश्य में, दोनों परतों में लेनदेन का प्रबंधन व्यर्थ है क्योंकि केवल एक ही लेनदेन है। यदि लेनदेन सी # कोड में शुरू किया गया है, तो संग्रहीत प्रक्रिया में होने वाली सभी चीजें BEGIN TRAN कहलाती है कि @@TRANCOUNT बढ़ी है। और लेनदेन वास्तव में तब तक प्रतिबद्ध नहीं है जब तक @@TRANCOUNTCOMMIT की समान संख्या जारी करके @@TRANCOUNT में दिखाया गया है (इस मामले में, संग्रहीत प्रक्रिया में COMMIT जारी करना और फिर सी # कोड में, जिस बिंदु पर SQL सर्वर वास्तव में वास्तविक "प्रतिबद्ध" करता है)। हालांकि, एक ROLLBACK@@TRANCOUNT वापस 0 लाता है इससे कोई फर्क नहीं पड़ता कि यह कितना नंबर था। और यदि यह संग्रहीत प्रक्रिया में होता है, तो आप सी # कोड में COMMIT या ROLLBACK जारी नहीं कर सकते क्योंकि लेनदेन अब मौजूद नहीं है, इसलिए आपको पहले एक सक्रिय लेनदेन की जांच करनी होगी।

मान लें कि आप कम से कम SQL सर्वर 2005 का उपयोग कर रहे हैं, यदि नया नहीं है, तो संग्रहीत प्रक्रिया के भीतर COMMIT/ROLLBACK प्रबंधित करने के लिए टी-एसक्यूएल TRY/CATCH वाक्यविन्यास का उपयोग करना सुनिश्चित करें। आपको ठीक से त्रुटियों को पकड़ने के लिए TRY/CATCH वाक्यविन्यास की आवश्यकता होगी और यदि आप केवल सी # कोड में लेनदेन का प्रबंधन कर रहे हैं तो भी proc (ओं) से बाहर निकलें।

उदाहरण के लिए:

BEGIN TRY 

    BEGIN TRAN; 

    UPDATE Table1 ... ; 

    UPDATE Table2 ... ; 

    UPDATE Table3 ... ; 

    COMMIT TRAN; 

END TRY 
BEGIN CATCH 

    IF (@@TRANCOUNT > 0) 
    BEGIN 
    ROLLBACK TRAN; 
    END; 

    THROW; -- if using SQL Server 2012 or newer, else use RAISERROR 

END CATCH; 
+0

ओह देवता, नेस्टेड एसक्यूएल सर्वर लेनदेन .. प्लेग की तरह से बचें। कम से कम ट्रिगर्स शामिल नहीं हैं। यह उन कुछ क्षेत्रों में से एक है जहां मैं एक मौका दिया, एक एसक्यूएल सर्वर डेवलपर लात मारूँगा। – user2864740

+0

बहुत बहुत धन्यवाद ... मैं एकाधिक एसक्यूएल कॉमांड निष्पादित कर रहा हूं और प्रत्येक आदेश एसक्यूएल सर्वर 2008 आर 2 में प्रो का उपयोग करके एकाधिक तालिकाओं को अपडेट कर रहा है, इसलिए यदि मैं केवल सी # कोड स्तर पर लेनदेन का उपयोग करता हूं, तो यह ठीक काम करेगा? –

+0

@ अभिषेक श्रीवास्तव: मेरे अपडेट किए गए उत्तर की जांच करें क्योंकि मैंने उस परिदृश्य को संबोधित किया है जबकि आप टिप्पणी जोड़ रहे होंगे ;-)। यह सब नीचे आता है कि उन संग्रहित प्रक्रियाओं को अन्य संग्रहीत प्रक्रियाओं द्वारा या अन्य सी # कोड द्वारा व्यक्तिगत रूप से बुलाया जा सकता है, जो लेनदेन में लिपटे नहीं हो सकते हैं। –

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