2009-04-17 16 views
6

मेरे पास एक वेब एप्लिकेशन है जो डीएएल में 3 डेटाबेस के लिए अनुरोध जारी करता है। मैं यह सुनिश्चित करने के लिए कुछ एकीकरण परीक्षण लिख रहा हूं कि समग्र कार्यक्षमता दौर यात्रा वास्तव में ऐसा करती है जो मैं अपेक्षा करता हूं। यह मेरे यूनिट परीक्षणों से बिल्कुल अलग है, बस fyi।यदि एमएसडीटीसी अक्षम है तो आप ट्रांज़ेक्शनस्कोप के अंदर एकाधिक डेटाबेस कनेक्शन कैसे प्राप्त करते हैं?

तरह से मैं इन परीक्षणों लिखने के लिए इच्छुक था इस मामले में पहले से ही प्रस्तुतकर्ता स्थापित किया गया है इस

[Test] 
public void WorkflowExampleTest() 
{ 
    (using var transaction = new TransactionScope()) 
    { 
     Presenter.ProcessWorkflow(); 
    } 
} 

के प्रभाव से कुछ थे। समस्या ProcessWorkflow विधि के अंदर खेलती है क्योंकि यह विभिन्न रिपोजिटरीज को कॉल करती है जो बदले में विभिन्न डेटाबेस तक पहुंचती हैं, और मेरे एसक्यूएल सर्वर बॉक्स में एमएसडीटीसी सक्षम नहीं है, इसलिए जब भी मैं एक नया एसक्यूएल कनेक्शन बनाने की कोशिश करता हूं, तो मुझे एक त्रुटि मिलती है, या कोशिश करें एक अलग को लक्षित करने के लिए एक कैश कनेक्शन के डेटाबेस को बदलने के लिए।

public void ProcessWorkflow() 
{ 
    LogRepository.LogSomethingInLogDatabase(); 
    var l_results = ProcessRepository.DoSomeWorkOnProcessDatabase(); 
    ResultsRepository.IssueResultstoResultsDatabase(l_results); 
} 

मैं इस समस्या को हल करने के लिए कई बातें का प्रयास किया है:

संक्षिप्तता के लिए प्रस्तुतकर्ता की तरह कुछ जैसा दिखता है।

  1. कैशिंग हर समय एक सक्रिय कनेक्शन और लक्ष्य डेटाबेस को बदलने
  2. कैशिंग प्रत्येक लक्ष्य डेटाबेस के लिए एक सक्रिय कनेक्शन (इस तरह के बेकार था, क्योंकि पूलिंग मेरे लिए यह करना चाहिए, लेकिन मैं अगर देखना चाहता था मैं अलग परिणाम मिल गया)
  3. प्रत्येक भंडार के अंदर अतिरिक्त TransactionScopes जोड़ा जा रहा है ताकि वे TransactionScopeOption "RequiresNew"

मेरी सूची पर 3 प्रयास कुछ इस तरह दिखता का उपयोग कर अपने स्वयं के लेनदेन:

public void LogSomethingInLogDatabase() 
{ 
    using (var transaction = 
     new TransactionScope(TransactionScopeOption.RequiresNew)) 
    { 
     //do some database work 

     transaction.Complete(); 
    } 
} 

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

इसलिए मेरा प्रश्न यह है कि मैं जो बाधाओं को पूरा कर रहा हूं, उसे पूरा करने के लिए क्या अन्य विकल्प हैं?

संपादित करें:

यह "// कुछ डेटाबेस काम करते हैं"

using (var l_context = new DataContext(TargetDatabaseEnum.SomeDatabase)) 
{ 
    //use a SqlCommand here 
    //use a SqlDataAdapter inside the SqlCommand 
    //etc. 
} 

और DataContext ही इस

public class DataContext : IDisposable 
{ 
    static int References { get; set; } 
    static SqlConnection Connection { get; set; } 

    TargetDatabaseEnum OriginalDatabase { get; set; } 

    public DataContext(TargetDatabaseEnum database) 
    { 
     if (Connection == null) 
      Connection = new SqlConnection(); 

     if (Connection.Database != DatabaseInfo.GetDatabaseName(database)) 
     { 
      OriginalDatabase = 
       DatabaseInfo.GetDatabaseEnum(Connection.Database); 

      Connection.ChangeDatabase(
       DatabaseInfo.GetDatabaseName(database)); 
     }   

     if (Connection.State == ConnectionState.Closed) 
     { 
      Connection.Open() //<- ERROR HAPPENS HERE 
     }  

     ConnectionReferences++;     
    } 

    public void Dispose() 
    { 
     if (Connection.State == ConnectionState.Open) 
     { 
      Connection.ChangeDatabase(
       DatabaseInfo.GetDatabaseName(OriginalDatabase)); 
     } 

     if (Connection != null && --ConnectionReferences <= 0) 
     { 
      if (Connection.State == ConnectionState.Open) 
       Connection.Close(); 
      Connection.Dispose(); 
     } 
    } 
} 
+0

मुझे यकीन नहीं है कि मैं अनुसरण करता हूं। काम की इकाई का मतलब क्या है? – Joseph

+0

क्षमा करें क्या हम यहां एकाधिक डेटाबेस सर्वर या एक सर्वर से एकाधिक कनेक्शन की बात कर रहे हैं? – meandmycode

+0

एक ही सर्वर पर एकाधिक डेटाबेस या विभिन्न सर्वरों पर एकाधिक डेटाबेस? यदि वे एक ही सर्वर पर हैं तो आपको उसी सर्वर पर MSDTC – SQLMenace

उत्तर

1

ठीक है, मुझे इस मुद्दे के आसपास एक रास्ता मिला। एकमात्र कारण यह है कि मैं इसे इस तरह से कर रहा हूं क्योंकि मुझे इस समस्या को ठीक करने का कोई और तरीका नहीं मिला, और क्योंकि यह मेरे एकीकरण परीक्षण में है, इसलिए मैं इस बारे में चिंतित नहीं हूं कि उत्पादन कोड में प्रतिकूल प्रभाव पड़ता है।

मुझे अपने डेटा कॉन्टेक्स्ट का निपटान होने पर कनेक्शन ऑब्जेक्ट का निपटान करने के बारे में ट्रैक रखने के लिए ध्वज के रूप में कार्य करने के लिए अपने डेटा कॉन्टेक्स्ट में एक संपत्ति जोड़नी पड़ती थी। इस तरह, कनेक्शन पूरे लेन-देन गुंजाइश भर जीवित रखा है, और इसलिए अब डीटीसी

परेशान यह मेरा नया निपटान का नमूना है:

internal static bool SupressConnectionDispose { get; set; } 

public void Dispose() 
{ 
    if (Connection.State == ConnectionState.Open) 
    { 
     Connection.ChangeDatabase(
      DatabaseInfo.GetDatabaseName(OriginalDatabase)); 
    } 

    if (Connection != null 
     && --ConnectionReferences <= 0 
     && !SuppressConnectionDispose) 
    { 
     if (Connection.State == ConnectionState.Open) 
      Connection.Close(); 
     Connection.Dispose(); 
    } 
} 

यह मेरा एकीकरण परीक्षण के रूप में लेने के लिए अनुमति देता है:

[Test] 
public void WorkflowExampleTest() 
{ 
    (using var transaction = new TransactionScope()) 
    { 
     DataContext.SuppressConnectionDispose = true; 

     Presenter.ProcessWorkflow(); 
    } 
} 

मैं उत्पादन कोड में इसका उपयोग करने की अनुशंसा नहीं करता, लेकिन एकीकरण परीक्षणों के लिए मुझे लगता है कि यह उचित है। यह भी ध्यान रखें कि यह केवल उन कनेक्शनों के लिए काम करता है जहां सर्वर हमेशा समान होता है, साथ ही साथ उपयोगकर्ता भी।

मुझे उम्मीद है कि यह किसी और की मदद करता है जो मेरे पास एक ही समस्या में चलता है।

0

तरह दिखता कैसा लगेगा क्या है आप तो एमएसडीटीसी का उपयोग नहीं करना चाहते हैं आप सीधे एसक्यूएल लेनदेन का उपयोग कर सकते हैं।

SqlConnection.BeginTransaction() देखें।

+0

यह एकीकरण परीक्षण के संदर्भ में कैसे काम करेगा? यदि मैं रिपोजिटरी स्तर पर BeginTransaction और Commit या Rollback का उपयोग करता हूं, तो क्या होगा जब मैं पूरी चीज़ को लेन-देन के दायरे में लपेटूं? – Joseph

1
  1. सेट लेनी चाहिए = false कनेक्शन स्ट्रिंग पर लेन-देन पर ऑटो भर्ती होने से बचने के लिए।

  2. लेन-देन के दायरे में प्रतिभागियों के रूप में मैन्युअल रूप से कनेक्शन दर्ज करें। (http://msdn.microsoft.com/en-us/library/ms172153%28v=VS.80%29.aspx)

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

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