जवाबों:
यहाँ कोड स्निपेट है:
using System.Transactions;
....
using (var transactionScope = new TransactionScope())
{
DoYourDapperWork();
transactionScope.Complete();
}
ध्यान दें कि आपको System.Transactionsअसेंबली का संदर्भ जोड़ने की आवश्यकता है क्योंकि यह डिफ़ॉल्ट रूप से संदर्भित नहीं है।
Dispose()विधि में करता है । अगर Complete()नहीं बुलाया गया है, तो लेनदेन वापस लुढ़का हुआ है।
TransctionScopeउपयोग ब्लॉक के अंदर खोला जाना चाहिए , यदि आप इस उत्तर को चुनते हैं।
मैंने कनेक्शन से सीधे लेनदेन प्राप्त करके अधिक सहज दृष्टिकोण का उपयोग करना पसंद किया:
// 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();
}
.BeginTransaction()
Execute, क्योंकि यह आवश्यक है।
आपको उपयोग करने में सक्षम होना चाहिए TransactionScopeक्योंकि डैपर सिर्फ ADO.NET कमांड चलाता है।
using (var scope = new TransactionScope())
{
// insert
// insert
scope.Complete();
}
आपकी सभी तालिकाएँ एकल डेटाबेस में होने के कारण, मैं TransactionScopeयहाँ कुछ उत्तरों में सुझाए गए समाधान से असहमत हूँ । इस उत्तर को देखें ।
TransactionScopeआम तौर पर वितरित लेनदेन के लिए उपयोग किया जाता है; अलग-अलग डेटाबेस में फैले लेन-देन अलग-अलग सिस्टम पर हो सकते हैं। इसके लिए ऑपरेटिंग सिस्टम और SQL सर्वर पर कुछ कॉन्फ़िगरेशन की आवश्यकता होती है जिसके बिना यह काम नहीं करेगा। यह अनुशंसित नहीं है यदि आपके सभी प्रश्न डेटाबेस के एकल उदाहरण के खिलाफ हैं।
लेकिन, एकल डेटाबेस के साथ यह तब उपयोगी हो सकता है जब आपको लेनदेन में कोड को शामिल करने की आवश्यकता होती है जो आपके नियंत्रण में नहीं है। एकल डेटाबेस के साथ, इसे विशेष कॉन्फ़िगरेशन की भी आवश्यकता नहीं है।
connection.BeginTransactionएकल डेटाबेस के विरुद्ध लेनदेन (C #, VB.NET आदि में) को लागू करने के लिए ADO.NET सिंटैक्स है। यह कई डेटाबेस में काम नहीं करता है।
इसलिए, connection.BeginTransaction() का बेहतर तरीका है।
यहां तक कि लेनदेन को संभालने का बेहतर तरीका UnitOfWork को लागू करना है जैसा कि इस उत्तर में बताया गया है ।
TransactionScopeजो ओपी चाहते हैं के लिए अक्षम है जो उपयोग करने का सुझाव देते हैं। मैं मानता हूँ कि TransactionScopeकई मामलों में अच्छा उपकरण है; लेकिन यह नहीं।
डैनियल के जवाब ने मेरे लिए उम्मीद के मुताबिक काम किया। पूर्णता के लिए, यहां एक स्निपेट है जो लेनदेन के दायरे और डैपर का उपयोग करके प्रतिबद्ध और रोलबैक प्रदर्शित करता है:
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
Disposeविधि को पहली या दूसरी कहा जाता है, बस इसे दो बार कहा जाता है। इस बिंदु के अनुसार कि "दूसरी बार कॉल करना हानिकारक नहीं है", यह एक बड़ी धारणा है। मैंने सीखा है कि डॉक्स और वास्तविक कार्यान्वयन अक्सर सहमत नहीं होते हैं। लेकिन अगर आप इसके लिए माइक्रोसॉफ्ट का शब्द चाहते हैं: msdn.microsoft.com/en-us/library/…