Dapper.net के साथ लेन-देन का उपयोग कैसे करें?


106

मैं कई टेबलों पर कई इंसर्ट स्टेटमेंट चलाना चाहूंगा। मैं dapper.net का उपयोग कर रहा हूं। मुझे dapper.net के साथ लेनदेन को संभालने का कोई तरीका नहीं दिखता है।

कृपया अपने विचारों को dapper.net के साथ लेन-देन का उपयोग करने के तरीके पर साझा करें।

जवाबों:


107

यहाँ कोड स्निपेट है:

using System.Transactions;    
....    
using (var transactionScope = new TransactionScope())
{
    DoYourDapperWork();
    transactionScope.Complete();
}

ध्यान दें कि आपको System.Transactionsअसेंबली का संदर्भ जोड़ने की आवश्यकता है क्योंकि यह डिफ़ॉल्ट रूप से संदर्भित नहीं है।


7
क्या यह स्पष्ट रूप से त्रुटि पर रोल करने के लिए आवश्यक है या System.Transactions को स्वचालित रूप से संभालता है?
नॉर्बर्ट नॉर्बरसन

6
@NorbertNorbertson इसे स्वचालित रूप से Dispose()विधि में करता है । अगर Complete()नहीं बुलाया गया है, तो लेनदेन वापस लुढ़का हुआ है।
the_joric 8

4
एक अन्य उत्तर ( stackoverflow.com/a/20047975/47672 ) के कारण उल्लेख करने के लिए : कनेक्शन का TransctionScopeउपयोग ब्लॉक के अंदर खोला जाना चाहिए , यदि आप इस उत्तर को चुनते हैं।
0x49D1

2
यह भी देखें ( stackoverflow.com/a/20047975/444469 ) - DoYouDapperWork (Execute, Query, आदि ...) को मापदंडों में लेनदेन की आवश्यकता है।
मैथ्यू

क्या समस्या होने पर रोलबैक स्वचालित रूप से कहा जाता है?
गंडालफ g ’१

91

मैंने कनेक्शन से सीधे लेनदेन प्राप्त करके अधिक सहज दृष्टिकोण का उपयोग करना पसंद किया:

// This called method will get a connection, and open it if it's not yet open.
using (var connection = GetOpenConnection())
using (var transaction = connection.BeginTransaction())
{
    connection.Execute(
        "INSERT INTO data(Foo, Bar) values (@Foo, @Bar);", listOf5000Items, transaction);
    transaction.Commit();
}

@ हंस: ठीक है, हम शायद अलग-अलग डैपर फ्रेमवर्क का उपयोग कर रहे हैं, क्योंकि यह एक है: github.com/StackExchange/dapper-dot-net
andrecarlucci

25
connection.open की है, कॉल () .begintransaction से पहले
टाइमलेस

जब तक आप लेन-देन के दायरे में कनेक्शन नहीं खोलते हैं, तब तक लेन-देनस्कोप में एक कनेक्शन स्वचालित रूप से सूचीबद्ध नहीं किया जाता है। मुझे नहीं पता कि आपका कोड कैसे काम करता है, अगर GetOpenConnection किसी तरह जादुई तरीके से खुद को लेन-देन के दायरे में खोलता है, लेकिन मैं चाहता हूं कि यह न हो
एरिक बर्गस्टेड

@ ErikBergstedt, क्या आप कह रहे हैं कि कनेक्शन केवल उस पर कॉल करने के बाद ही खुला होना चाहिए ? यदि ऐसा होता, तो यह विस्तार पद्धति लेनदेन के गलत उपयोग को बढ़ावा देती। (IMO, यह "कनेक्शन पहले से ही खुला होने के बाद भी लेन-देन नहीं कर सकता है" फेंकना चाहिए।).BeginTransaction()
एवेज़

2
लेनदेन को एक पैरामीटर के रूप में शामिल करने के लिए अच्छा बिंदु Execute, क्योंकि यह आवश्यक है।
सिस्टाद

19

आपको उपयोग करने में सक्षम होना चाहिए TransactionScopeक्योंकि डैपर सिर्फ ADO.NET कमांड चलाता है।

using (var scope = new TransactionScope())
{
   // insert
   // insert
   scope.Complete();
}

8

आपकी सभी तालिकाएँ एकल डेटाबेस में होने के कारण, मैं TransactionScopeयहाँ कुछ उत्तरों में सुझाए गए समाधान से असहमत हूँ । इस उत्तर को देखें ।

  1. TransactionScopeआम तौर पर वितरित लेनदेन के लिए उपयोग किया जाता है; अलग-अलग डेटाबेस में फैले लेन-देन अलग-अलग सिस्टम पर हो सकते हैं। इसके लिए ऑपरेटिंग सिस्टम और SQL सर्वर पर कुछ कॉन्फ़िगरेशन की आवश्यकता होती है जिसके बिना यह काम नहीं करेगा। यह अनुशंसित नहीं है यदि आपके सभी प्रश्न डेटाबेस के एकल उदाहरण के खिलाफ हैं।
    लेकिन, एकल डेटाबेस के साथ यह तब उपयोगी हो सकता है जब आपको लेनदेन में कोड को शामिल करने की आवश्यकता होती है जो आपके नियंत्रण में नहीं है। एकल डेटाबेस के साथ, इसे विशेष कॉन्फ़िगरेशन की भी आवश्यकता नहीं है।

  2. connection.BeginTransactionएकल डेटाबेस के विरुद्ध लेनदेन (C #, VB.NET आदि में) को लागू करने के लिए ADO.NET सिंटैक्स है। यह कई डेटाबेस में काम नहीं करता है।

इसलिए, connection.BeginTransaction() का बेहतर तरीका है।

यहां तक ​​कि लेनदेन को संभालने का बेहतर तरीका UnitOfWork को लागू करना है जैसा कि इस उत्तर में बताया गया है ।


4
TransactionScope से लाभ उठाने के लिए किसी को कई डेटाबेस की आवश्यकता नहीं होती है। विशेष उपयोगिता की है कि यह परिवेश है। यह उस कोड को रैप करने के लिए बहुत अच्छा है जिसे आप लेन-देन में नहीं लेते या संशोधित नहीं कर सकते। उदाहरण के लिए इसका उपयोग उस महान प्रभाव के लिए किया जा सकता है जब यूनिट / एकीकरण परीक्षण कोड जो डेटाबेस कॉल करता है, जहां आप बाद में वापस रोल करना चाहते हैं। बस एक TransactionScope फ्लोट करें, कोड का परीक्षण करें, और परीक्षण क्लीनअप के दौरान निपटान करें।
लैरी स्मिथ

3
@LarrySmith: सहमत; लेकिन सवाल इस बारे में कुछ भी नहीं है। ओपी सिर्फ यह कहता है कि वह एक लेनदेन में कई तालिकाओं में सम्मिलित होना चाहता है। स्वीकार किए गए एक सहित कुछ जवाब, TransactionScopeजो ओपी चाहते हैं के लिए अक्षम है जो उपयोग करने का सुझाव देते हैं। मैं मानता हूँ कि TransactionScopeकई मामलों में अच्छा उपकरण है; लेकिन यह नहीं।
अमित जोशी

5

डैनियल के जवाब ने मेरे लिए उम्मीद के मुताबिक काम किया। पूर्णता के लिए, यहां एक स्निपेट है जो लेनदेन के दायरे और डैपर का उपयोग करके प्रतिबद्ध और रोलबैक प्रदर्शित करता है:

using System.Transactions;
    // _sqlConnection has been opened elsewhere in preceeding code 
    using (var transactionScope = new TransactionScope())
    {
        try
        {
            long result = _sqlConnection.ExecuteScalar<long>(sqlString, new {Param1 = 1, Param2 = "string"});

            transactionScope.Complete();
        }
        catch (Exception exception)
        {
            // Logger initialized elsewhere in code
            _logger.Error(exception, $"Error encountered whilst executing  SQL: {sqlString}, Message: {exception.Message}")

            // re-throw to let the caller know
            throw;
        }
    } // This is where Dispose is called 

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

@CodeNaked, पहले, आपको वहां ऑर्डर गलत मिला है। यदि कोई अपवाद है तो कैच ब्लॉक को पहले हिट किया जाएगा, फिर उपयोग करने की गुंजाइश समाप्त होगी। दूसरा, इस उत्तर को देखें और संदर्भित MSDN doc: stackoverflow.com/a/5306896/190476 कॉलिंग डिस्पोज़ दूसरी बार हानिकारक नहीं है, एक अच्छी तरह से डिज़ाइन की गई वस्तु दूसरी कॉल को अनदेखा करती है। चढ़ाव उचित नहीं है!
सुधांशु मिश्र

@dotnetguy - मुझे यह बताने की कोशिश नहीं की गई कि कौन सी Disposeविधि को पहली या दूसरी कहा जाता है, बस इसे दो बार कहा जाता है। इस बिंदु के अनुसार कि "दूसरी बार कॉल करना हानिकारक नहीं है", यह एक बड़ी धारणा है। मैंने सीखा है कि डॉक्स और वास्तविक कार्यान्वयन अक्सर सहमत नहीं होते हैं। लेकिन अगर आप इसके लिए माइक्रोसॉफ्ट का शब्द चाहते हैं: msdn.microsoft.com/en-us/library/…
21

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