2009-08-13 12 views
23

मैंने थोड़ा सी # विधि "विरासत" प्राप्त की है जो डेटाबेस (SQL सर्वर 2005) में सहेजे जाने वाले आइटम्स की एक सूची पर ADO.NET SqlCommand ऑब्जेक्ट और लूप बनाता है।एडीओ.NET रिफैक्टरिंग - एसक्यूएलट्रांसक्शन बनाम ट्रांज़ेक्शनस्कोप

अभी, पारंपरिक SqlConnection/SqlCommand दृष्टिकोण का उपयोग किया जाता है, और यह सुनिश्चित करने के लिए कि सब कुछ काम करता है, दो चरणों (पुरानी प्रविष्टियों को हटाएं, फिर नए डालें) को ADO.NET SqlTransaction में लपेटा जाता है।

using (SqlConnection _con = new SqlConnection(_connectionString)) 
{ 
    using (SqlTransaction _tran = _con.BeginTransaction()) 
    { 
     try 
     { 
     SqlCommand _deleteOld = new SqlCommand(......., _con); 
     _deleteOld.Transaction = _tran; 
     _deleteOld.Parameters.AddWithValue("@ID", 5); 

     _con.Open(); 

     _deleteOld.ExecuteNonQuery(); 

     SqlCommand _insertCmd = new SqlCommand(......, _con); 
     _insertCmd.Transaction = _tran; 

     // add parameters to _insertCmd 

     foreach (Item item in listOfItem) 
     { 
      _insertCmd.ExecuteNonQuery(); 
     } 

     _tran.Commit(); 
     _con.Close(); 
     } 
     catch (Exception ex) 
     { 
      // log exception 
      _tran.Rollback(); 
      throw; 
     } 
    } 
} 

अब, मैं हाल ही में नेट TransactionScope वर्ग बारे में बहुत कुछ पढ़ रहा है, और मैं सोच रहा था, क्या पसंद किया दृष्टिकोण यहाँ है? क्या मुझे

using (TransactionScope _scope = new TransactionScope()) 
{ 
    using (SqlConnection _con = new SqlConnection(_connectionString)) 
    { 
    .... 
    } 

    _scope.Complete(); 
} 

का उपयोग करने के लिए स्विच करके कुछ भी (पठनीयता, गति, विश्वसनीयता) प्राप्त होगा, और आप क्यों पसंद करेंगे?

मार्क

उत्तर

14

TransactionScope का उपयोग करने के लिए आपको अपने मौजूदा कोड को स्विच करके तुरंत कुछ हासिल नहीं होगा। भविष्य में विकास के लिए इसका उपयोग करना चाहिए क्योंकि यह लचीलापन प्रदान करता है। इससे भविष्य में एडीओ.NET के अलावा अन्य चीजों को लेनदेन में शामिल करना आसान हो जाएगा।

बीटीडब्लू, आपके पोस्ट उदाहरण में, SqlCommand उदाहरण using ब्लॉक में होना चाहिए।

+0

ठीक है, धन्यवाद जॉन - और हाँ, आप सही हैं - इस उदाहरण में() ब्लॉक (अभी तक!) का उपयोग करने में SqlCommand नहीं है - यह प्रगति पर है :-) –

+0

पुन: SQLCommand उपयोग के अंदर, क्या कोई है कचरा संग्रह के अलावा अन्य कारण, उदाहरण के लिए: SQLConnection के लिए निपटान() बंद करें() विधि को कॉल करता है, इसलिए किसी भी SQLCommand विधियों को अस्वीकार() को कॉल करता है? –

+3

यदि कोई वर्ग 'आईडीस्पोजेबल' लागू करता है, और यदि आप इस कक्षा का उदाहरण बनाते हैं, तो आपको उस पर निपटान करना चाहिए। ऐसा करने का सबसे आसान तरीका 'उपयोग' ब्लॉक के साथ है। मुझे हमेशा एक को लागू करने की आदत में जाना सर्वोत्तम होता है। –

9

माइक्रोसॉफ्ट लेनदेन गुंजाइश उपयोग करने की सलाह:

http://msdn.microsoft.com/en-us/library/system.transactions.transactionscope.aspx

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

लेनदेन का दायरा आपके लिए काम करता है, ताकि आप नलसाजी की बजाय सिस्टम की कार्यक्षमता पर ध्यान केंद्रित कर सकें।

संपादित

आपको लगता है कि दायरे के भीतर एक सौदे गुंजाइश सब कुछ का उपयोग करते हैं लेन-देन से आच्छादित है। इसलिए, आप कोड की एक पंक्ति को सहेजते हैं, जहां आप लेनदेन में कमांड को कनेक्ट करते हैं। यह त्रुटि का एक संभावित स्रोत है, उदाहरण के लिए यदि 1000 में एक मौका था कि यह लाइन भूल गई थी, तो आप कितने खो जाएंगे।

संपादित 2

नीचे Triynko पर टिप्पणी के साथ सहमत हूँ। हालांकि, हम एंटीटी फ्रेमवर्क का उपयोग करते हैं, ईएफ लेनदेन में इसे सूचीबद्ध करने के लिए स्वचालित रूप से कनेक्शन बंद कर देगा और फिर से खोल देगा। यह कनेक्शन को शारीरिक रूप से बंद नहीं करता है, यह इसे कनेक्शन पूल में रिलीज़ करता है और एक नया प्राप्त करता है, जो एक जैसा हो सकता है या एक अलग हो सकता है।

+0

ठीक है। उसके लिए धन्यवाद। लेकिन क्या मुझे किसी भी तरह से फायदा होता है, अगर मैं ADO.NET एम्बेडेड लेनदेन के बजाय लेनदेनस्कोप() का उपयोग करने के लिए सब कुछ दोहराता हूं (यह सिर्फ एक नमूना नहीं है)? सिर्फ यह पूछना कि क्या प्रयास इसके लायक है - मुझे इससे क्या फायदा होगा? –

+8

"जब आप उस दायरे में लेनदेन के दायरे का उपयोग करते हैं तो लेनदेन द्वारा कवर किया जाता है।" नहीं, सबकुछ ढंका नहीं है। दायरे में सूचीबद्ध कनेक्शन पर जारी किए गए केवल आदेश दायरे से प्रभावित होते हैं। यदि स्कोप में खोला गया है तो कनेक्शन स्वचालित रूप से दायरे में सूचीबद्ध हो जाते हैं, अन्यथा पहले से खोले गए कनेक्शनों को एसक्यूएलकनेक्शन.इनलिस्ट ट्रांज़ेक्शन को कॉल करके बनाए जाने के बाद मैन्युअल रूप से दायरे में सूचीबद्ध किया जाना चाहिए। यदि आप, उदाहरण के लिए, अपना कनेक्शन खोलें, तो लेनदेन का दायरा बनाएं ... आपके कोई भी आदेश लेनदेन में शामिल नहीं होगा। – Triynko

+0

@Triynko: संबंधित एमएसडीएन लेख के लिए आपकी टिप्पणी बहुत बढ़िया है! – abatishchev

6

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

7

मैं लेनदेनस्कोप पसंद करता हूं। यह हर परिदृश्य में पूरी तरह से काम नहीं करता है, लेकिन जिस वर्णन में आप वर्णन करते हैं, यह बेहतर समाधान है।

मेरे तर्क:

  1. लेन-देन में Enlistment स्वचालित है
  2. एक अपवाद की स्थिति में
  3. लेन-देन रोलबैक

एक साथ स्वचालित है, परिणाम थोड़ा कम कोड और एक आम तौर पर है अधिक मजबूत डिजाइन, क्योंकि सिस्टम मेरे लिए कुछ विवरण संभालने वाला है; यह एक कम बात है जो मुझे याद रखना है।

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

2

ठीक है, शायद इस बात के लिए बहुत देर हो चुकी है ... लेकिन वैसे भी, मैं इसे रुचि रखने वालों के लिए लिख देंगे ...

जब से मैं अब बेहतर तस्वीर है, मेरे वर्तमान के साथ कठिनाइयों का एक बहुत होने के बाद SqlTransaction आधारित दृष्टिकोण जो मैं TransactionScope के पक्ष में बदल सकता हूं, जैसा कि मैंने इसे देखा है ... TransactionScope का मुख्य लाभ यह है कि यह बिजनेस लेयर में बहुत आसानी से उपयोग किया जा सकता है।

2

भी देर से ... आप आसानी से व्यापार परत में "घोंसला" लेनदेन कर सकते हैं भले ही डेटाबेस नेस्टेड लेनदेन का समर्थन नहीं करता है। .NET घोंसले को नियंत्रित करता है और एक डेटाबेस लेनदेन का उपयोग कर समाप्त होता है (कम से कम SQL सर्वर 2008+ के मामले में)। इससे बड़े लेनदेन के हिस्से के रूप में, अपने मूल उद्देश्य के बाहर डेटा एक्सेस कोड का पुन: उपयोग करना अधिक आसान हो जाता है।

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