2012-07-10 27 views
6

हम धीरे-धीरे इकाई ढांचे (4.3.1) द्वारा विरासत डेटा एक्सेस कोड को बदलने की प्रक्रिया में हैं। कुछ अवसरों में हम काम की एक इकाई में डेटा पहुंच के दोनों तरीकों का उपयोग करने से नहीं बच सकते हैं। आदर्श रूप में, यह एक लेनदेन में किया जाना चाहिए। हालांकि, पुराना कोड SqlTransaction एस का उपयोग करता है जो Commit() पर कॉल करता है जब काम की एक इकाई होती है और ईएफ अपने लेनदेन का प्रबंधन करता है।SqlTransaction को अनदेखा करें। लेनदेनस्कोप के भीतर टिप्पणी

तो हमने TransactionScope में "पुराना" और "नया" कोड लपेटने का विचार किया। हालांकि, आसपास के TransactionScope के भीतर एक कमिटिट हमेशा निष्पादित होती है, भले ही TransactionScope पूरा नहीं हुआ हो। यह कोड स्निपेट मेरी समस्या दिखाता है:

using (var conn = new SqlConnection("connection string")) 
{ 
    conn.Open(); 
    using (var scope = new TransactionScope()) 
    { 
    using (var tr = conn.BeginTransaction()) 
    { 
     using (var cmd = conn.CreateCommand()) 
     { 
     cmd.Transaction = tr; 
     cmd.CommandText = "some update statement"; 
     cmd.ExecuteNonQuery(); 
     } 
     tr.Commit(); 
    } 
    // In reality the code above is part of a legacy DAL, immutable. 
    // (can't insert SaveChanges before tr.Commit). 
    context.SaveChanges(); 
    if (<all ok>) // pseudo code for exception handling. 
     scope.Complete(); 
    } 
} 

अद्यतन बयान अभी भी लिए प्रतिबद्ध है जब scope.Complete() मारा नहीं है।

तो ऐसा लगता है कि, मैं एक लेनदेन में निष्पादित करने के लिए पुराने डेटा एक्सेस कोड और SaveChanges को लागू करने के लिए TransactionScope का उपयोग नहीं कर सकता। या SqlTransaction.Commit कथन को ओवरराल करने का कोई तरीका है?

मुझे पता है कि अधिक पोस्ट यहाँ TransactionScope और SqlTransaction के बारे में हैं कि, लेकिन वे सभी (ठीक ही) का कहना है कि SqlTransaction का उपयोग करके आवश्यक (और न ही अनुशंसित) नहीं है जब TransactionScope का उपयोग कर। लेकिन SqlTransaction का उपयोग नहीं करना यहां एक विकल्प नहीं है। हमारे पास एक विरासत ढांचा है जो अपने SqlTransaction एस करता है और उसके लेनदेन तंत्र में शामिल होने के लिए कोई एपीआई नहीं है।

+0

क्या आपके पास कम से कम कनेक्शन तक पहुंच है? –

+0

@ LadislavMrnka नहीं, कॉन्फ़िगरेशन फ़ाइल में कनेक्शन स्ट्रिंग के अलावा। –

उत्तर

7

स्कोप के दौरान अद्यतन कथन अभी भी प्रतिबद्ध है। पूर्ण() हिट नहीं है।

ओह नहीं !! TransacationScope का उपयोग नहीं किया जा रहा है ।

ऑटो भर्ती केवल काम करता है अगर कनेक्शन खुला हैके बाद (या अंदर) TransactionScope।

लाना Open अंदर TransactionScope के रूप में कनेक्शन तो [आम तौर पर] परिवेश टीएस संदर्भ में ऑटो भर्ती जाएगा (यहां तक ​​कि मैनुअल लेनदेन के साथ?) इस समस्या को हल करना चाहिए।

परिवेश लेनदेन के दायरे में एक मौजूदा कनेक्शन को सूचीबद्ध किया जा सकता है: connection.EnlistTransaction(Transaction.Current)

वैकल्पिक रूप से, टीएस मौजूदा लेनदेन से बनाया जा सकता है, उदाहरण के लिए new TransactionScope(transaction), जो यहां सहायक हो सकता है या नहीं भी हो सकता है।

एक मैनुअल लेन-देन करता है, तो बिल्कुल ठीक बनाना, लेकिन टीएस (gotchas के बाद पता लगा रहे हैं!) ज्यादातर मामलों :) में कम से कम सरल और आसान लेनदेन के साथ काम करता है ..

मुबारक कोडिंग!


टीएस "अद्यतन बयान" के लिए इस्तेमाल किया जा रहा है।यह अभी भी [संभावित] context.SaveChanges() के लिए उपयोग किया जाएगा क्योंकि यह नया कनेक्शन खोल देगा जो तब स्वत: सूचीबद्ध है।

मैंने ऊपर कुछ विकल्प प्रदान किए हैं, हालांकि मैं सादा "नेस्टेड" लेनदेन के बारे में अनिश्चित हूं। संदर्भ में उपयोग किए गए (मुहरबंद?) एपीआई को देखकर सीमाओं/प्रतिबंधों के रूप में अधिक अंतर्दृष्टि प्रकट हो सकती है।

+0

आप सही हैं! जब मैं टीएस के बाद 'ओपन' डालता हूं तो टीएस अग्रणी होता है। और मुझे लगता है कि वास्तव में यह भी होना चाहिए, क्योंकि पुराने ढांचे के अंदर कनेक्शन खोला गया है। लेकिन यह अभी भी काम करता है। मुझे वहां क्या हो रहा है में थोड़ा गहराई से पता लगाना होगा और देखें कि आपके सुझावों में से कोई एक इसे ठीक कर सकता है या नहीं। धन्यवाद, मैं इस पर वापस आऊंगा। –

+0

यह मुझे सही रास्ते पर लाया। मुझे पता चला है कि पुराने ढांचे के कनेक्शन से अधिक लंबे समय तक खुला रहता है। तो ट्रांसएक्शनस्कोप का उपयोग करना असंभव है जिस तरह से मैं पुराने कोड को बदलने के बिना चाहूंगा - जिसे हम करने में बहुत अनिच्छुक हैं। मुझे डर है कि हमें करना है। –

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

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