.Net में लेन-देन


144

C # .net 2.0 में लेन-देन करने के लिए सर्वोत्तम अभ्यास क्या हैं। वे कौन से वर्ग हैं जिनका उपयोग किया जाना चाहिए? आदि के लिए देखने के लिए जो नुकसान होते हैं वे सब कमिट और रोलबैक सामान हैं। मैं सिर्फ एक परियोजना शुरू कर रहा हूं, जहां मुझे डीबी में डेटा सम्मिलित करते समय कुछ लेनदेन करने की आवश्यकता हो सकती है। लेनदेन के बारे में बुनियादी बातों के लिए कोई प्रतिक्रिया या लिंक का स्वागत है।


प्रारंभ के रूप में उपयोग करने के लिए कोडप्रोजेक्ट पर .NET में लेनदेन का एक अच्छा उदाहरण है ।
मिचेल सेलर्स

जवाबों:


271

लेनदेन के 2 मुख्य प्रकार हैं; कनेक्शन लेनदेन और परिवेश लेनदेन। एक कनेक्शन लेन-देन (जैसे SqlTransaction) सीधे db कनेक्शन (जैसे SqlConnection) से बंधा होता है, जिसका अर्थ है कि आपको कनेक्शन को पास रखना होगा - कुछ मामलों में ठीक है, लेकिन "बनाने / उपयोग" की अनुमति नहीं देता है " उपयोग, और क्रॉस-डीबी कार्य की अनुमति नहीं देता है। एक उदाहरण (अंतरिक्ष के लिए स्वरूपित):

using (IDbTransaction tran = conn.BeginTransaction()) {
    try {
        // your code
        tran.Commit();
    }  catch {
        tran.Rollback();
        throw;
    }
}

बहुत गड़बड़ नहीं है, लेकिन हमारे कनेक्शन "कॉन" तक सीमित है। यदि हम अलग-अलग तरीकों से कॉल करना चाहते हैं, तो हमें अब "कॉन" पास करना होगा।

विकल्प एक परिवेश लेनदेन है; .NET 2.0 में नया, TransactionScope ऑब्जेक्ट (System.Transactions.dll) कई प्रकार के ऑपरेशनों का उपयोग करने की अनुमति देता है (उपयुक्त प्रदाता स्वचालित रूप से परिवेशी लेनदेन में सूचीबद्ध होंगे)। यह मौजूदा (गैर-लेन-देन) कोड में रेट्रो-फिट करने के लिए आसान बनाता है, और कई प्रदाताओं से बात करने के लिए (हालांकि यदि आप एक से अधिक से बात करते हैं तो डीटीसी शामिल हो जाएगा)।

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

using(TransactionScope tran = new TransactionScope()) {
    CallAMethodThatDoesSomeWork();
    CallAMethodThatDoesSomeMoreWork();
    tran.Complete();
}

यहाँ ध्यान दें कि दो विधियाँ अपने स्वयं के कनेक्शन (ओपन / यूज़ / क्लोज़ / डिस्पोज़) को हैंडल कर सकती हैं, फिर भी वे चुपचाप परिवेश के लेन-देन का हिस्सा बन जाएंगे, हमारे बिना कुछ भी पास होने के लिए नहीं।

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

TransactionScope का अन्य लाभ यह है कि यह केवल डेटाबेस से बंधा नहीं है; कोई भी लेनदेन-जागरूक प्रदाता इसका उपयोग कर सकता है। उदाहरण के लिए, WCF। या यहां तक ​​कि कुछ TransactionScope- संगत ऑब्जेक्ट मॉडल भी हैं (यानी .NET क्लासेज रोलबैक क्षमता के साथ - शायद एक स्मृति चिन्ह की तुलना में आसान है, हालाँकि मैंने कभी इस दृष्टिकोण का उपयोग नहीं किया है)।

सब सब में, एक बहुत, बहुत उपयोगी वस्तु।

कुछ चेतावनी:

  • SQL Server 2000 पर, एक TransactionScope तुरंत DTC पर जाएगा; यह SQL Server 2005 और इसके बाद के संस्करण में तय किया गया है, यह LTM (बहुत कम ओवरहेड) का उपयोग तब तक कर सकता है जब तक कि आप 2 स्रोतों आदि से बात नहीं करते हैं, जब यह डीटीसी को ऊपर उठाया जाता है।
  • एक गड़बड़ है जिसका अर्थ है कि आपको अपने कनेक्शन स्ट्रिंग को ट्विक करने की आवश्यकता हो सकती है

CSLA .NET 2.0 TransactionScope ऑब्जेक्ट का समर्थन करता है!
बिनोज एंटनी

यहां समस्या तब है जब आपके पास पहली विधि में लेन-देन है और यह विधि (इनकैप्सुलेशन) को नहीं पता है कि माता-पिता के लेनदेन से बुलाया जाएगा या नहीं।
एडुआर्डो मोल्टनी

1
@Eduardo - यह TransactionScope का उपयोग करते समय कोई समस्या नहीं है, जो इसे बहुत आकर्षक बनाता है। इस तरह के लेन-देन घोंसला, और केवल सबसे बाहरी लेनदेन करता है।
मार्क Gravell

मुझे आशा है कि आप अभी भी सुन रहे हैं। आपने कहा कि "आसपास कुछ TransactionScope- संगत ऑब्जेक्ट मॉडल हैं"। क्या आप मुझे उनमें से कुछ की ओर इशारा कर सकते हैं? धन्यवाद।
मेजकिनटोर

1
फिर से मार्क, एक और उत्कृष्ट व्याख्या। जब आप कहते हैं कि 'अपेक्षित नेस्टिंग समर्थित है' तो यह है कि लेनदेन के तरीकों के लिए परिभाषित तरीके (CallAMethodThatDoesSomeWork (उदाहरण के लिए) स्वयं)? या लेन-देन के बाहर के साथ परिभाषित, यह आवश्यक नहीं है?
फिल कूपर

11
protected void Button1_Click(object sender, EventArgs e)
   {


       using (SqlConnection connection1 = new SqlConnection("Data Source=.\\SQLEXPRESS;AttachDbFilename=|DataDirectory|\\Database.mdf;Integrated Security=True;User Instance=True"))
       {
           connection1.Open();

           // Start a local transaction.
           SqlTransaction sqlTran = connection1.BeginTransaction();

           // Enlist a command in the current transaction.
           SqlCommand command = connection1.CreateCommand();
           command.Transaction = sqlTran;

           try
           {
               // Execute two separate commands.
               command.CommandText =
                "insert into [doctor](drname,drspecialization,drday) values ('a','b','c')";
               command.ExecuteNonQuery();
               command.CommandText =
                "insert into [doctor](drname,drspecialization,drday) values ('x','y','z')";
               command.ExecuteNonQuery();

               // Commit the transaction.
               sqlTran.Commit();
               Label3.Text = "Both records were written to database.";
           }
           catch (Exception ex)
           {
               // Handle the exception if the transaction fails to commit.
               Label4.Text = ex.Message;


               try
               {
                   // Attempt to roll back the transaction.
                   sqlTran.Rollback();
               }
               catch (Exception exRollback)
               {
                   // Throws an InvalidOperationException if the connection 
                   // is closed or the transaction has already been rolled 
                   // back on the server.
                   Label5.Text = exRollback.Message;

               }
           }
       }


   }

4

आप लेन-देन को स्वयं संग्रहीत प्रक्रिया में भी लपेट सकते हैं और इसे C # में लेन-देन करने के बजाय इसे संभाल सकते हैं।


1

अगर आपको सिर्फ db-related सामान की आवश्यकता है, तो कुछ OR Mappers (जैसे NHibernate) प्रति डिफॉल्ट रूप से बॉक्स से बाहर ट्रांसएक्टिनो का समर्थन करते हैं।


0

यह इस बात पर भी निर्भर करता है कि आपको क्या चाहिए। मूल SQL लेनदेन के लिए आप अपने कोड में BEGIN TRANS और COMMIT TRANS का उपयोग करके TSQL लेनदेन कर सकते हैं। यह सबसे आसान तरीका है, लेकिन इसमें जटिलता नहीं है और आपको ठीक से (और रोलबैक) करने के लिए सावधान रहना होगा।

मैं कुछ का उपयोग करता हूँ

SQLTransaction trans = null;
using(trans = new SqlTransaction)
{
    ...
    Do SQL stuff here passing my trans into my various SQL executers
    ...
    trans.Commit  // May not be quite right
}

कोई भी विफलता आपको सही से बाहर कर देगी usingऔर लेन-देन हमेशा कमिट करेगा या रोलबैक करेगा (यह निर्भर करता है कि आप इसे क्या करते हैं)। हमारे सामने सबसे बड़ी समस्या यह सुनिश्चित करने की थी कि यह हमेशा प्रतिबद्ध रहे। उपयोग सुनिश्चित करता है कि लेनदेन का दायरा सीमित है।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.