2012-11-24 29 views
97

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

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

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

"लेनदेन स्कोप गलत तरीके से घोंसला।"।

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

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

+0

यहाँ छोड़कर अपवाद यहां लेन-देन निरस्त की जाती है कि – Yann

+0

तुम सिर्फ एक नियमित रूप से एसक्यूएल लेनदेन का उपयोग एनआईटी कर सकते हैं एक TransactionScope त्रुटि http://pastebin.com/Eh1dxG4a पुन: पेश करने के लिए एक बहुत ही सरल कोड है? या आप कई संसाधनों को फैला रहे हैं? –

+0

मैं एकाधिक संसाधनों को फैला रहा हूं – Yann

उत्तर

6

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

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(); 
} 

Managing Concurrency with DependentTransaction

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

+1

एडम प्रेस्कॉट का उदाहरण बाल कार्य async चिह्नित नहीं किया गया था। यदि आप 'प्रतीक्षा करें टास्क। डेले (500)' जैसी कुछ चीज़ों के साथ "लेनदेन संबंधी सामान" को प्रतिस्थापित करते हैं, तो यह पैटर्न 'ट्रांज़ेक्शनस्कोप गलत तरीके से घोंसला' के साथ भी असफल हो जाएगा क्योंकि बाहरी ट्रांज़ेक्शनस्कोप (उपरोक्त उदाहरण में नहीं दिखाया गया है) बच्चे के कार्य से पहले दायरे से बाहर निकलता है पूरा करता है। 'टास्क.एट()' के साथ 'प्रतीक्षा करें' को बदलें और यह काम करता है, लेकिन फिर आपने 'async' के लाभ खो दिए हैं। – mdisibio

+0

समस्या को हल करने का यह एक कठिन तरीका है। लेनदेनस्कोप उन सभी नलसाजी को छिपाना है। – Eniola

138

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

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

// 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(); 
} 
9

थोड़ी देर हो चुकी एक जवाब के लिए, लेकिन मैं MVC4 के साथ एक ही समस्या आ रहा था और मैं 4.5 से 4.5 करने के लिए अपने प्रोजेक्ट अद्यतन:

मेरे समझ है कि यह आप इस तरह कोड लिखने की अनुमति देने के लिए किया जाता है .1 परियोजना पर राइट क्लिक करके गुणों पर जाएं। आवेदन टैब को लक्ष्य ढांचे को 4.5.1 में बदलें और अनुसरण के रूप में लेनदेन का उपयोग करें।

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

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

  • कोई संबंधित समस्या नहीं^_^