Async / प्रतीक्षा के साथ काम करने के लिए TransactionScope प्राप्त करें


114

मैं हमारी सेवा बस में एकीकृत async/ करने की कोशिश कर रहा हूं await। मैंने SingleThreadSynchronizationContextइस उदाहरण के आधार पर http://blogs.msdn.com/b/pfxteam/archive/2012/01/20/10259049.aspx को लागू किया ।

और यह ठीक काम करता है, एक चीज को छोड़कर TransactionScope:। मैं अंदर सामान का इंतजार करता हूं TransactionScopeऔर यह टूट जाता है TransactionScope

TransactionScopeasync/ के साथ अच्छा खेल नहीं लगता है await, निश्चित रूप से क्योंकि यह धागे का उपयोग करके चीजों को संग्रहीत करता है ThreadStaticAttribute। मुझे यह अपवाद मिलता है:

"TransactionScope ने गलत तरीके से नेस्ट किया।"

मैंने TransactionScopeकार्य को पंक्तिबद्ध करने से पहले डेटा को सहेजने और इसे चलाने से पहले इसे पुनर्स्थापित करने की कोशिश की, लेकिन यह एक चीज़ को बदलने के लिए नहीं लगता है। और TransactionScopeकोड एक गड़बड़ है, इसलिए यह समझना मुश्किल है कि वहां क्या हो रहा है।

क्या इसे काम करने का कोई तरीका है? क्या कोई विकल्प है TransactionScope?


यहाँ TransactionScope त्रुटि pastebin.com/Eh1dxG4a को पुन: उत्पन्न करने के लिए एक बहुत ही सरल कोड है, सिवाय इसके कि यहां अपवाद लेन-देन निरस्त है
Yann

क्या आप सिर्फ एक नियमित एसक्यूएल लेनदेन का उपयोग कर सकते हैं? या आप कई संसाधनों को फैला रहे हैं?
मार्क Gravell

मैं कई राशियों का विस्तार कर रहा हूं
यवन

ऐसा लगता है कि आपको या तो गुंजाइश को अपने async विधि में पारित करना होगा, या इसे किसी प्रकार के सामान्य संदर्भ से पुनर्प्राप्त करने का एक तरीका देना होगा जो आपकी कार्य इकाई के साथ पहचाना जाता है।
बर्ट्रेंड ले रॉय

आपको SingleThreadSynchronizationContextप्रत्येक शीर्ष-स्तर के लिए एक अलग थ्रेड की आवश्यकता होगी TransactionScope
स्टीफन क्लीयर

जवाबों:


161

.NET फ्रेमवर्क 4.5.1 में, एक पैरामीटर लेने के लिए नए कंस्ट्रक्टरTransactionScope का एक सेट है TransactionScopeAsyncFlowOption

MSDN के अनुसार, यह थ्रेड निरंतरता में लेनदेन प्रवाह को सक्षम करता है।

मेरी समझ यह है कि यह आपको इस तरह कोड लिखने की अनुमति देने के लिए है:

// transaction scope
using (var scope = new TransactionScope(... ,
  TransactionScopeAsyncFlowOption.Enabled))
{
  // connection
  using (var connection = new SqlConnection(_connectionString))
  {
    // open connection asynchronously
    await connection.OpenAsync();

    using (var command = connection.CreateCommand())
    {
      command.CommandText = ...;

      // run command asynchronously
      using (var dataReader = await command.ExecuteReaderAsync())
      {
        while (dataReader.Read())
        {
          ...
        }
      }
    }
  }
  scope.Complete();
}

10

एक उत्तर के लिए थोड़ी देर हो गई लेकिन मुझे MVC4 के साथ एक ही मुद्दा था और मैंने अपने प्रोजेक्ट को संपत्तियों पर क्लिक करके 4.5 से 4.5.1 तक अद्यतन किया। एप्लिकेशन टैब परिवर्तन लक्ष्य रूपरेखा को 4.5.1 पर चुनें और लेनदेन का पालन करें।

using (AccountServiceClient client = new AccountServiceClient())
using (TransactionScope scope = new TransactionScope(TransactionScopeAsyncFlowOption.Enabled))
{
}


6

आप Transaction.D dependentClone () विधि द्वारा बनाई गई DependentTransaction का उपयोग कर सकते हैं :

static void Main(string[] args)
{
  // ...

  for (int i = 0; i < 10; i++)
  {

    var dtx = Transaction.Current.DependentClone(
        DependentCloneOption.BlockCommitUntilComplete);

    tasks[i] = TestStuff(dtx);
  }

  //...
}


static async Task TestStuff(DependentTransaction dtx)
{
    using (var ts = new TransactionScope(dtx))
    {
        // do transactional stuff

        ts.Complete();
    }
    dtx.Complete();
}

निर्भरता के साथ प्रबंध संगति

http://adamprescott.net/2012/10/04/transactionscope-in-multi-threaded-applications/


2
एडम प्रेस्कॉट का उदाहरण चाइल्ड टास्क async के रूप में चिह्नित नहीं किया गया था। यदि आप "do Transactional stuff" को कुछ await Task.Delay(500)इस तरह से बदलते हैं तो यह पैटर्न भी विफल हो जाएगा TransactionScope nested incorrectlyक्योंकि सबसे बाहरी TransactionScope (उपरोक्त उदाहरण में नहीं दिखाया गया है) चाइल्ड टास्क को ठीक से पूरा करने से पहले स्कोप को बाहर निकाल देता है। के awaitसाथ बदलें Task.Wait()और यह काम करता है, लेकिन फिर आप के लाभों को खो दिया है async
mdisibio

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