2015-12-08 12 views
8

में नेस्टेड लेनदेन व्यवहार वर्तमान में मैं अपनी डेटा परत में लेनदेन प्रबंधित करने के लिए ट्रांज़ेक्शनस्कोप का उपयोग कर रहा हूं, लेकिन मैं नेस्टेड लेनदेन और एसिंक के साथ मुद्दों में भाग ले रहा हूं जिससे कनेक्शन नेस्टेड लेनदेन के दौरान बंद हो रहा है या लेनदेन को बढ़ावा दिया जाता है एमएसडीटीसी के लिए। मुझे सही समस्या नहीं मिली है लेकिन इसके आसपास पढ़ने के बाद ऐसा लगता है कि यह परिदृश्य particuarly well समर्थित नहीं है और मुझे इसके बजाय डेटाबेस.बिनरट्रांसक्शन() का उपयोग करना चाहिए।ईएफ 6

मेरी समस्या यह है कि मुझे डाटाबेस.बिनरट्रांसक्शन() नेस्टेड लेनदेन के साथ काम करता है, विशेष रूप से मेरे परिदृश्य में जहां मैं एक नया निर्माण करने के बजाय परिवेश लेनदेन का उपयोग करना चाहता हूं, इस बारे में जानकारी नहीं मिल पा रहा हूं। मेरा संदेह यह है कि यह इस तरह से काम करने का इरादा नहीं है और यदि मैं नेस्टेड लेनदेन का प्रबंधन करना चाहता हूं तो मुझे अधिक नियंत्रण देने के लिए लेनदेन प्रबंधन को अवगत कराया जाना चाहिए।

अवशेषों की अनावश्यक परतों में शामिल नहीं करना चाहते हैं, मैं जानना चाहता हूं कि किसी के पास इस क्षेत्र में अनुभव है या नहीं और डेटाबेस के व्यवहार की पुष्टि कर सकता है। BginginTransaction() जब किसी अन्य लेनदेन के अंदर घोंसला होता है?

मेरी दाल के बारे में अतिरिक्त जानकारी:

public class AddBlogPostHandler 
{ 
    private readonly MyDbContext _myDbContext; 

    public AddBlogPostHandler(MyDbContext myDbContext) 
    { 
     _myDbContext = myDbContext; 
    } 

    public async Task ExecuteAsync(AddBlogPostCommand command) 
    { 
     using (var scope = new TransactionScope(TransactionScopeAsyncFlowOption.Enabled)) 
     { 
      // .. code to create and add a draft blog post to the context 
      await _myDbContext.SaveChangesAsync(); 

      var publishBlogPostCommand = new PublishBlogPostCommand(); 
      // ..set some variables on the PublishBlogPostCommand 
      await PublishBlogPostAsync(command); 

      scope.Complete(); 
     } 
    } 
} 

public class PublishBlogPostHandler 
{ 
    private readonly MyDbContext _myDbContext; 

    public PublishBlogPostHandler(MyDbContext myDbContext) 
    { 
     _myDbContext = myDbContext; 
    } 

    public async Task ExecuteAsync(PublishBlogPostCommand command) 
    { 
     using (var scope = new TransactionScope(TransactionScopeAsyncFlowOption.Enabled)) 
     { 
      // .. some code to do one set of update 
      await _myDbContext.SaveChangesAsync(); 

      // .. some other db updates that need to be run separately 
      await _myDbContext.SaveChangesAsync(); 

      scope.Complete(); 
     } 
    } 
} 

उत्तर

5

वहाँ: CQS पैटर्न के आधार पर मैंने आदेश या क्वेरी संचालकों में Db संबंधित कोड को संपुटित होगा करता है, इसलिए एक सरल/कैसे इस घोंसले होता है की काल्पनिक उदाहरण नेस्टेड लेन-देन जैसी कोई चीज इस अर्थ में नहीं है कि आंतरिक व्यक्ति स्वतंत्र रूप से प्रतिबद्ध या रोलबैक कर सकता है। नेस्टेड लेनदेन वास्तव में केवल एक रेफरी गिनती बनाए रखते हैं। आखिरी प्रतिबद्धता में हमें शारीरिक प्रतिबद्धता मिलती है। पहले रोलबैक में हमें भौतिक रोलबैक मिलता है। बस यह सुनिश्चित कर लें कि आप इसके बारे में जानते हैं।

एमएसडीटीसी उपयोग से बचना महत्वपूर्ण है। यह TransactionScope और BeginTransaction दोनों के साथ संभव है। पूर्व के साथ आपको स्पष्ट रूप से Open दायरे के अंदर कनेक्शन की आवश्यकता है ताकि ईएफ हर समय नए कनेक्शन नहीं खोल सके।

जैसा कि आपने इस मुद्दे को पढ़ा है, यह ईएफ में एक दोष है (जो एल 2 एस नहीं था)। कृपया यह सुनिश्चित करने के लिए इस मुद्दे पर टिप्पणी करने का समय लें कि टीम को पता है कि ग्राहक इस समस्या में भाग रहे हैं।

विशेष रूप से मेरे परिदृश्य में जहां मैं एक नया निर्माण करने के बजाय परिवेश लेनदेन का उपयोग करना चाहता हूं।

यह TransactionScope के लिए बिल्कुल सही है। मुझे लगता है कि BeginTransaction पर आपका स्विच गलतफहमी पर आधारित है। शायद आप टिप्पणियों में स्पष्टीकरण दे सकते हैं।

पुष्टि Database.BeginTransaction के व्यवहार() जब एक और लेन-देन

पहले अनुच्छेद में समझाया अंदर नेस्टेड।

मेरी दाल के बारे में अतिरिक्त जानकारी: CQS पैटर्न के आधार पर मैंने आदेश या क्वेरी संचालकों में Db संबंधित कोड है, तो एक सरल/कैसे इस घोंसले होता होगा की काल्पनिक उदाहरण संपुटित करते हैं:

गायब db.Connection.Open() कॉल (जैसा ऊपर बताया गया है) को छोड़कर कोड ठीक दिखता है।

यह पैटर्न एक ही लेनदेन में कई प्रश्नों और आदेशों को निष्पादित करने में सहायता करेगा।बस इसके चारों ओर एक और गुंजाइश लपेटो। दो बार कनेक्शन खोलना सुनिश्चित करें, उदा। कार्रवाई करने से पहले conn.State देखें।

+0

मुझे लगता है कि मैं वास्तव में पूछ रहा हूँ अगर 'BeginTransaction' को एक नेस्टेड कॉल एक नई लेन-देन (' TransactionScopeOption.RequiresNew' के बराबर) बनाता है या परिवेश लेन-देन ('TransactionScopeOption.Required' के बराबर) का उपयोग करता है? इसे काम करने में असमर्थता के अलावा, 'BeginTransaction' पर स्विच ईएफ 6 + के लिए उनकी सिफारिश पर आधारित था। मैं इसे 'ट्रांज़ेक्शनस्कोप' के साथ काम करने की कोशिश करने के लिए खुला हूं, लेकिन यदि मैं मैन्युअल रूप से कनेक्शन खोलता हूं तो बाहरी लेनदेन पूरा होने से पहले मुझे अपवाद मिलता है (लेनदेन "पूरा हो गया है लेकिन इसका निपटारा नहीं किया गया है") –

+1

BeginTransaction आवश्यक है। एक ही कनेक्शन पर एकाधिक ट्रांस होने का कोई तरीका नहीं है। इसलिए, यह संभवतः RequiresNew की तरह व्यवहार नहीं कर सकता है। 'ईएफ 6' के लिए उनकी सिफारिश होने के कारण मैंने इसे भी पढ़ा लेकिन मुझे लगता है कि कोई तर्क नहीं दिया गया था। अजीब सलाह। 'बाहरी लेनदेन पूरा होने से पहले मुझे अपवाद मिलता है' मुझे लगता है कि आपको बग की जांच करनी चाहिए और ठीक करना चाहिए। पूरे दृष्टिकोण को क्यों छोड़ दें यदि आपको केवल एक मामूली बग ठीक करना है? – usr

+0

ग्रेट, मुझे पता नहीं था कि प्रति कनेक्शन केवल एक लेनदेन हो सकता है। मैं अपने परिदृश्य में काम करने के लिए 'ट्रांजैक्शनस्कोप' नहीं कर सका, इसलिए मैंने एक छोटे से अमूर्त लेखन को समाप्त कर दिया जिसका मतलब था कि मेरे पास घोंसले हुए लेन-देन के क्षेत्र हो सकते हैं और अभी भी अंतर्निहित लेनदेन के लिए 'डेटाबेस.बिनरट्रांसक्शन' का उपयोग कर सकते हैं। आपकी मदद @usr के लिए धन्यवाद –

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