2009-04-06 19 views
14

हमें लेनदेनस्कोप का उपयोग करने में समस्या है। लेनदेन स्कोप हमारे डेटा एक्सेस लेयर में लेनदेन का उपयोग करने के लिए हमें बहुत अच्छी लचीलापन प्राप्त करता है। इस तरह हम लेनदेन को स्पष्ट या स्पष्ट उपयोग कर सकते हैं। एडीओ.NET लेनदेन को फिर से कुछ प्रदर्शन बढ़ावा मिला है, लेकिन इस समय यह वास्तव में समस्या नहीं है। हालांकि हमें लॉकिंग में समस्या है। उदाहरण के लिए नीचे कोड, हालांकि अलगाव स्तर को पढ़ा गया है, हालांकि तालिका परीक्षण पर अन्य क्लाइंट से एसक्यूएल कथन का चयन करना संभव नहीं है, जब तक मुख्य लेनदेन (मुख्य विधि में) नहीं किया जाएगा, क्योंकि पूरे टेबल पर लॉक है। हमने सभी विधियों में केवल एक कनेक्शन का उपयोग करने की कोशिश की, लेकिन एक ही व्यवहार। हमारा डीबीएमएस एसक्यूएल सर्वर 2008 है। क्या ऐसा कुछ है जिसे हम समझ में नहीं आया?लेनदेनस्कोप और अलगाव स्तर

class Program 
{ 
    public class DAL 
    { 
     private const string _connectionString = @"Data Source=localhost\fsdf;Initial Catalog=fasdfsa;Integrated Security=SSPI;"; 

     private const string inserttStr = @"INSERT INTO dbo.testTable (test) VALUES(@test);"; 

     /// <summary> 
     /// Execute command on DBMS. 
     /// </summary> 
     /// <param name="command">Command to execute.</param> 
     private void ExecuteNonQuery(IDbCommand command) 
     { 
      if (command == null) 
       throw new ArgumentNullException("Parameter 'command' can't be null!"); 

      using (IDbConnection connection = new SqlConnection(_connectionString)) 
      { 
       command.Connection = connection; 
       connection.Open(); 
       command.ExecuteNonQuery(); 
      } 
     } 

     public void FirstMethod() 
     { 
      IDbCommand command = new SqlCommand(inserttStr); 
      command.Parameters.Add(new SqlParameter("@test", "Hello1")); 

      using (TransactionScope sc = new TransactionScope(TransactionScopeOption.Required)) 
      { 
       ExecuteNonQuery(command); 
       sc.Complete(); 
      } 
     } 

     public void SecondMethod() 
     { 
      IDbCommand command = new SqlCommand(inserttStr); 
      command.Parameters.Add(new SqlParameter("@test", "Hello2")); 

      using (TransactionScope sc = new TransactionScope(TransactionScopeOption.Required)) 
      { 
       ExecuteNonQuery(command); 
       sc.Complete(); 
      } 
     } 
    } 

    static void Main(string[] args) 
    { 

     DAL dal = new DAL(); 
     TransactionOptions tso = new TransactionOptions(); 
     tso.IsolationLevel = System.Transactions.IsolationLevel.ReadCommitted; 

     using (TransactionScope sc = new TransactionScope(TransactionScopeOption.Required,tso)) 
     { 
      dal.FirstMethod(); 
      dal.SecondMethod(); 
      sc.Complete(); 
     } 
    } 
} 

उत्तर

19

मुझे नहीं लगता कि आपकी समस्या का नेट TransactionScope अवधारणा से कोई लेना देना नहीं है है:

सादर एंटोन Kalcik

इस नमूना कोड देखें। इसके बजाय, ऐसा लगता है कि आप SQL सर्वर लेनदेन के अपेक्षित व्यवहार का वर्णन कर रहे हैं। साथ ही, अलगाव स्तर को बदलना केवल "डेटा पढ़ता है" को प्रभावित करता है, "डेटा लिखता है" नहीं। एसक्यूएल सर्वर बोल से:।

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

क्या है कि मतलब है कि आप ग्राहकSELECT कथन (नों) जारी करने के लिए अलगाव स्तर बदलकर अवरुद्ध व्यवहार को रोका जा सकता है। READ COMMITED अलगाव स्तर (डिफ़ॉल्ट) अवरुद्ध करने से नहीं रोकेगा। क्लाइंट को अवरुद्ध करने से रोकने के लिए, आप READ UNCOMMITTED अलगाव स्तर का उपयोग करेंगे, लेकिन आपको संभावना है कि रिकॉर्ड्स को पुनर्प्राप्त किया जा सकता है जिसे एक खुले लेनदेन द्वारा अपडेट/डाला गया है (यानी लेनदेन वापस आने पर वे दूर जा सकते हैं) ।

+0

आपके संकेत के लिए धन्यवाद। तो अगर इसे सही समझा जाता है, तो ट्रांज़ेक्शनस्कोप पर लेनदेन अलगाव स्तर की सेटिंग्स केवल इस लेनदेन के दायरे से डीबीएमएस पर पढ़ने के ऑपरेशन द्वारा डेटा तक पहुंचने में सक्षम होगी। –

9

लेनदेन के बारे में बात करने के लिए अच्छा सवाल।

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

यहाँ पहली विधि रिटर्न के बाद है:

First method returns

दूसरी विधि रिटर्न के बाद, आप तालिका के लिए एक और ताला जोड़ देगा।

secont method returns

हम SPID (55) के साथ एक प्रश्न खिड़की से चयन बयान पर अमल तो आपको स्थिति का इंतजार देखेंगे।

select is waiting

के बाद आप मुख्य विधि पार करता है, आप कुछ चुनिंदा बयान परिणाम मिल जाएगा और यह केवल हमारे select बयान क्वेरी पेज से ताला साझा दिखाएगा।

Scope commits and select returns

एक्स, अनन्य लॉक का मतलब नौवीं आशय ताले। You can read more from my blog post about transactions

यदि आप बिना प्रतीक्षा किए पढ़ना चाहते हैं, तो आप नोलॉक संकेत का उपयोग कर सकते हैं। यदि आप पहली विधि के बाद पढ़ना चाहते हैं, तो आप उस बाहरी दायरे को हटा सकते हैं।

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