2012-10-27 34 views
8

कॉल निम्नलिखित कोड का उपयोग करने वाले एक वैध सत्र है कि सुनिश्चित करने के लिए चल रहे EntityFramework गतिरोध को रोकने के लिए। यदि एक वैध सत्र मिला तो यह सत्र विवरण अपडेट करता है और परिवर्तनों को बचाता है। सब कुछ आसान है और ठीक काम करता है।जब समवर्ती इन दो बयानों अपने वेब सेवा में

// Create the Entity Framework context 
using(MyContext ctx = CreateMyContext()) 
{ 
    // Get the user session for the client session   
    UserSession session = (from us in context.UserSessions.Include("UserEntity") 
          where us.SessionId = callerSessionId 
          select us).FirstOrDefault<UserSession>(); 

    if (session == null) 
     return false; 
    else 
    { 
     // Update session details 
     session.Calls++; 
     session.LastAccessed = DateTime.Now.Ticks; 
     Console.WriteLine("Call by User:{0}", session.UserEntity.Name); 

     // Save session changes back to the server 
     ctx.SaveChanges(); 
     return true; 
    }  
} 

सभी एक ही फोन करने वाले जब तक ठीक काम करता है, और इसलिए एक ही सत्र, कई समवर्ती कॉल (जो पूरी तरह से होने की मान्य है) बनाता है। इस मामले में मुझे कभी-कभी डेडलॉक मिलता है। SQL सर्वर प्रोफाइलर का उपयोग करके मैं देख सकता हूं कि निम्न हो रहा है।

कोलर एक का चयन करता है और उपयोगकर्ता के सत्र पर एक साझा ताला प्राप्त कर लेता है। कॉलर बी एक ही उपयोगकर्ता सत्र पर साझा लॉक का चयन करता है और प्राप्त करता है। कॉलर ए कॉलर बी के साझा लॉक के कारण अपना अपडेट नहीं कर सकता है। कॉलर ए के साझा लॉक के कारण कॉलर बी अपना अपडेट नहीं कर सकता है। गतिरोध।

यह एक सरल और क्लासिक गतिरोध परिदृश्य की तरह लगता है और वहाँ इसे सुलझाने के लिए एक सरल विधि होना चाहिए। निश्चित रूप से लगभग सभी असली दुनिया के अनुप्रयोगों में भी यही समस्या है। लेकिन किसी भी इकाई फ्रेमवर्क पुस्तकें में मैंने डेडलॉक्स के बारे में कुछ भी उल्लेख नहीं किया है।

उत्तर

11

मैं एक लेख है कि इस बारे में बात करती HERE पाया। यह मूल रूप से लगता है जैसे आप अपने ईएफ कॉल से घिरे लेनदेन को शुरू और बंद कर सकते हैं ... ब्लॉक निम्नलिखित कोड उदाहरण देता है, इसलिए क्रेडिट डिएगो बी वेगा में जाता है ... ब्लॉग पोस्ट अतिरिक्त जानकारी के साथ किसी अन्य ब्लॉग से लिंक भी करता है।

using (var scope = new TransactionScope(TransactionScopeOption.Required, new 
    TransactionOptions { IsolationLevel= IsolationLevel.Snapshot })) 
{ 
    // do something with EF here 
    scope.Complete(); 
} 
+0

क्या मैं इस पर एक प्रश्न पूछ सकता हूं। क्या (MyContext ctx ..) का उपयोग करना चाहिए (var scope = new TransactionScope) या दूसरी तरफ? धन्यवाद। – Raj

+0

मेरा मानना ​​है कि आप 'ट्रांजैक्शनस्कोप' को 'MyContext' के अंदर होना चाहते हैं। मेरे दिमाग में बस इसके बारे में सोच रहा है ... क्योंकि लेनदेन का उपयोग * संदर्भ के लिए किया जा रहा है ... लेनदेन समाप्त होने पर संदर्भ मौजूद होना चाहिए। हालांकि यहां गलत हो सकता है। – Jared

1

क्या आपके लिए निम्नलिखित कार्य होगा?

using(MyContext ctx = CreateMyContext()) 
{ 

    ctx.Database.ExecuteSqlCommand("SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;"); 


    // Get the user session for the client session   
    ... 
}