2015-09-05 5 views
6

मुझे अपने डीबी में एक ही लेनदेन में कुछ टेबल अपडेट करने की आवश्यकता है और मैंने पढ़ा है कि DbContext.SaveChanges का उपयोग करने का तरीका होना चाहिए।इकाई फ्रेमवर्क डीबीकॉन्टेक्स्ट और थ्रेड सुरक्षा

हालांकि मैंने यह भी पढ़ा कि DbContext का जीवनकाल जितना संभव हो उतना छोटा होना चाहिए क्योंकि यह समय के साथ बढ़ता है क्योंकि यह अधिक इकाइयों को लोड करता है।

इसके अलावा मैंने यह भी पढ़ा कि इसे थ्रेड-सुरक्षित बनाने के लिए, प्रत्येक क्रिया का अपना DbContext होना चाहिए।

क्या मेरे पास प्रत्येक तालिका के लिए DbContext होना चाहिए, जिसे मैं बदलना चाहता हूं और प्रत्येक DbContext पर SaveChanges पर कॉल करना चाहता हूं? अंतिम SaveChanges कॉल पिछले कॉल के परिवर्तनों को ओवरराइड नहीं करेगा?

ऐसा करने का सबसे अच्छा तरीका क्या है? (मुझे इसकी वेबसाइट के लिए इसकी आवश्यकता है)

+0

यदि आप इसे एक ही लेनदेन में करना चाहते हैं तो एक एकल डीबीकॉन्टेक्स्ट ठीक है। थ्रेड सुरक्षा के बारे में चिंता करने की आवश्यकता नहीं है, हालांकि आपको अपने सभी परिचालनों को अनुक्रमिक रूप से करने की आवश्यकता होगी। – DavidG

+0

@ डेविड जी: लेकिन क्या होगा यदि 2 उपयोगकर्ता एक ही समय में एक ही डीबीकॉन्टेक्स्ट का उपयोग करने का प्रयास करते हैं? क्या यह रेस की स्थिति नहीं पैदा करेगा? – Idov

+0

आपको ऐसा होने की अनुमति कभी नहीं देना चाहिए। डीबीकॉन्टेक्स्ट का उपयोग इस तरह से नहीं किया जाना चाहिए और यदि आप कोशिश करते हैं तो कुछ बहुत ही अजीब चीजें करेंगे! – DavidG

उत्तर

1

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

मूल रूप से डीबीकॉन्टेक्स्ट कुछ भी नहीं करता है, यह सिर्फ डेटाबेस को लक्षित करने के लिए SQL क्वेरी कतार देता है, यह डेटाबेस है जो बहु थ्रेडिंग, दौड़ की स्थिति को संभालता है। अपने डेटा की रक्षा के लिए, आपको लेन-देन का उपयोग करें और अपने डेटाबेस में सत्यापन जोड़ना चाहिए यकीन है कि वे सही ढंग से सहेजे जाते हैं

public abstract class DbContextController : Controller{ 

    public AppDbContext DB { get; private set;} 

    public DbContextController(){ 
     DB = new AppDbContext(); 
    } 

    protected override void OnDisposing(bool disposing){ 
     DB.Dispose(); 
    } 

} 

आप DbContextController से किसी भी वर्ग के वारिस और नियंत्रक के जीवन भर डीबी का उपयोग करते हैं बनाने के लिए, आप की जरूरत नहीं होगी कोई परेशानी।

public ActionResult ProcessProducts(){ 
    foreach(var p in DB.Products){ 
     p.Processed = true; 
     foreach(var order in p.Orders){ 
      order.Processed = true; 
     } 
    } 
    DB.SaveChanges(); 
} 

लेकिन, आप निम्न उदाहरण में जैसे किसी भी धागे का उपयोग करते हैं,

public ActionResult ProcessProducts(){ 
    Parallel.ForEach(DB.Products, p=>{ 
     p.Processed = true; 
     // this fails, as p.Orders query is fired 
     // from same DbContext in multiple threads 
     foreach(var order in p.Orders){ 
      order.Processed = true; 
     } 
    }); 
    DB.SaveChanges(); 
} 
1

Entity Framework is not thread-safeAn MVC controller is instantiated per request। इस प्रकार यदि आप प्रति अनुरोध एक डीबीकॉन्टेक्स्ट का उपयोग करते हैं, तो आप तब तक सुरक्षित रहेंगे जब तक आप अपने नियंत्रक कार्यों में मैन्युअल रूप से थ्रेड नहीं करते हैं (जिसे आपको वैसे भी नहीं करना चाहिए)।

अब अगर आप अपने आवेदन में संगामिति, एक आरक्षण प्रणाली जहां अनेक उपयोगकर्ता एक ही दुर्लभ संसाधनों है कि बाहर (टिकट) की तरह चला सकते हैं का उपयोग करने के बाहर हैं जैसे है, तो आप अपने आप को कि चारों ओर तर्क को लागू करना होगा। वैसे भी कोई धागा सुरक्षा आपकी मदद करने जा रही है।

यही कारण है कि आपको टिप्पणियों में कोड के लिए कहा जा रहा है, क्योंकि सामान्य रूप से थ्रेड सुरक्षा की व्याख्या करना बहुत व्यापक है, और शायद आपकी स्थिति पर लागू नहीं है।

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