2011-02-26 11 views
7

मैं अपने अगले नए ऐप्स के लिए ईएफ का मूल्यांकन कर रहा हूं।सभी इकाई फ्रेमवर्क लेनदेन के अलगाव स्तर को वैश्विक स्तर पर बदलने के लिए

मैं आवेदन में सभी ईएफ लेनदेन के अलगाव स्तर को कैसे बदल सकता हूं? पूर्व: मान लीजिए कि मैं "प्रतिबद्ध स्नैपशॉट पढ़ें" का उपयोग करना चाहता हूं।

हालांकि अलगाव लेवल को निर्दिष्ट करना ठीक है, जब भी मुझे स्पष्ट रूप से एक ट्रांज़ेक्शनस्कोप की आवश्यकता है (नीचे कोड देखें) यह बदसूरत रूप से एक ट्रांज़ेक्शनस्कोप में हर ईएफ सेव ऑपरेशन को समाहित करने के लिए बदसूरत होगा।

'OK 
    Using tsc As New TransactionScope(TransactionScopeOption.RequiresNew, TransactionOption.ReadCommitted) 
     UpdateShoppingCart 
     EnqueueNewOrder 
     SendConfirmationEmail 
     tsc.Complete 
    End Using 

    'Is this really the only way to avoid Serializable? 
    Using tsc As New TransactionScope(TransactionScopeOption.RequiresNew, TransactionOption.ReadCommitted) 
     _ctx.SaveChanges() 
     tsc.Complete 
    End Using 

    Class TransactionOption 
     Public Shared ReadOnly ReadCommitted As New TransactionOptions() With { 
      .IsolationLevel = IsolationLevel.ReadCommitted, 
      .Timeout = TransactionManager.DefaultTimeout 
      } 
    End Class 

मुझे लगता है कि मिश्रण अलगाव लेवल एक अच्छा विचार नहीं है। क्या मैं इसके साथ गलत हूँ?

सीरियलज़ेबल और एसक्यूएल सर्वर (ओरेकल के विपरीत) के साथ एक साधारण निर्दोष दिखने वाले पढ़ने को एक रूपांतरण लॉक डेडलॉक का कारण बन सकता है।

एफई पूछे जाने वाले प्रश्न से: "यह अनुशंसित है कि आप पढ़ें कमिट लेनदेन का उपयोग करें और पढ़ें कमिट स्नैपशॉट अलगाव उपयोग करें यदि आप लेखकों और लेखकों पाठकों ब्लॉक नहीं ब्लॉक नहीं पाठकों की आवश्यकता है।"

मुझे समझ में नहीं आता कि ईएफ सीरियलज़ेबल के लिए क्यों डिफ़ॉल्ट है और डिफ़ॉल्ट अलगाव स्तर को बदलने में इतना मुश्किल बनाता है - SQL सर्वर (ओरेकल के बहु-संस्करण के विपरीत) एक निराशावादी समरूपता मॉडल के लिए डिफ़ॉल्ट है। कॉन्फ़िगरेशन विकल्प को कार्यान्वित करना बहुत आसान होना चाहिए - या क्या मुझे यहां कुछ याद आ रहा है?

+2

आप कहां से ईरियल को Serializable में डिफ़ॉल्ट पाया? –

उत्तर

9

मुझे लगभग यकीन है कि डिफ़ॉल्ट ईएफ लेनदेन अलगाव स्तर प्रयुक्त डेटाबेस प्रदाता पर आधारित है। SaveChanges इस कोड को निष्पादित करता है:

... 
    try 
    { 
     this.EnsureConnection(); 
     flag = true; 
     Transaction current = Transaction.Current; 
     bool flag2 = false; 
     if (connection.CurrentTransaction == null) 
     { 
      flag2 = null == this._lastTransaction; 
     } 
     using (DbTransaction transaction = null) 
     { 
      if (flag2) 
      { 
       transaction = connection.BeginTransaction(); 
      } 
      objectStateEntriesCount = this._adapter.Update(this.ObjectStateManager); 
      if (transaction != null) 
      { 
       transaction.Commit(); 
      } 
     } 
    } 
    ... 

आप देख सकते हैं BeginTransactionIsolationLevel निर्दिष्ट बिना कहा जाता है। हुड के तहत यह IsolationLevel.Unspecified के साथ प्रदाता विशिष्ट लेनदेन बनाता है। निर्दिष्ट अलगाव स्तर डेटाबेस सर्वर/ड्राइवर के लिए डिफ़ॉल्ट अलगाव स्तर का परिणाम होना चाहिए। SQL सर्वर डिफ़ॉल्ट अलगाव स्तर READ COMMITED है इसलिए मुझे उम्मीद है कि इसका उपयोग करना चाहिए लेकिन मैंने अभी तक इसका परीक्षण नहीं किया है।

आप परिवर्तन अलगाव स्तर आप अपने वर्ग ObjectContext से व्युत्पन्न में SaveChanges ओवरराइड और कस्टम TransactionScope में base.SaveChanges() लपेट कर सकते हैं विश्व स्तर पर चाहते हैं।

+0

आप सही हैं, मेरी धारणा गलत थी। परीक्षण करते समय शायद मैं निम्न समस्या में ठोकर खाई: http://connect.microsoft।कॉम/एसक्यूएल सर्वर/फीडबैक/विवरण/243527/एसपी-रीसेट-कनेक्शन-नहीं-रीसेट-अलगाव-स्तर मैंने सत्यापित किया कि SQL सर्वर के साथ ईएफ का डिफ़ॉल्ट एक SqlConnection.ClearAllPools() पहले कर रहा है और SQLProfiler के साथ जांच कर रहा है । –

0

VB में एक सीमा हो सकती है, लेकिन सी # में आप इस तरह यह करना होगा:

TransactionOptions transactionOptions = GetTransactionOptions(); 
new TransactionScope(TransactionScopeOption.RequiresNew, transactionOptions) 

ध्यान दें कि दूसरा पैरामीटर transactionOptions है, यह इस प्रकार बनाया जा सकता है:

public TransactionOptions GetTransactionOptions() 
    { 
     TransactionOptions transactionOptions = new TransactionOptions(); 
     transactionOptions.IsolationLevel = IsolationLevel.ReadCommitted; 
     return transactionOptions; 
    } 

उपरोक्त कोड को फ़ैक्टरी विधि में डालकर, और जब भी आपको लेन-देन विकल्पों की आवश्यकता होती है तो उस फैक्ट्री विधि को कॉल करके, आपके पास अपने समाधान में सभी लेनदेन स्कॉप्स बदलने के लिए एक स्थान हो सकता है।

+1

यह वही है जो मैंने अपने प्रश्न में पोस्ट किए गए कोड में किया था :-) मैं प्रत्येक को संलग्न करने के लिए एक रास्ता तलाश रहा हूं। एसएफ़ चेंज को एक ट्रांज़ेक्शनस्कोप के साथ ईएफ के डिफ़ॉल्ट सीरियलज़ेबल को बदलने के लिए प्रतिबद्ध स्नैपशॉट पढ़ने के लिए। –

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