2010-03-23 16 views
12

मेरे पास एक नियमित है जो एक SQL सर्वर 2005 डेटाबेस में आइटम डालने के लिए रिकर्सिव लूप का उपयोग करता है पहला लूप जो लूप शुरू करता है लेनदेन स्कोप का उपयोग कर लेनदेन के भीतर संलग्न होता है। जब मैं पहली बार ProcessItem को कॉल करता हूं तो myItem डेटा अपेक्षित रूप से डेटाबेस में डाला जाता है। हालांकि जब ProcessItem को ProcessItemLinks या ProcessItemComments से बुलाया जाता है तो मुझे निम्न त्रुटि मिलती है।लेनदेनस्कोप ऑपरेशन वैध क्यों नहीं है?

मैं विंडोज 7 पर वी.एस. 2008 के साथ डिबग में यह चला रहा हूँ "आपरेशन लेन-देन के राज्य के लिए मान्य नहीं है" और MSDTC वितरित लेनदेन सुनिश्चित करना चल रहा है। नीचे दिया गया कोड मेरा उत्पादन कोड नहीं है लेकिन बिल्कुल वही सेट है। AddItemToDatabase एक वर्ग पर एक विधि है जिसे मैं संशोधित नहीं कर सकता और मानक ExecuteNonQuery() का उपयोग करता हूं जो एक कनेक्शन बनाता है और फिर पूरा हो जाता है और बंद हो जाता है।

मैंने यहां और इंटरनेट पर अन्य पोस्टिंग देखी है और अभी भी इस समस्या को हल नहीं कर सकते हैं। कोई भी सहायताकाफी प्रशंसनीय होगी।

using (TransactionScope processItem = new TransactionScope()) 
{ 
    foreach (Item myItem in itemsList) 
    { 
     ProcessItem(myItem); 
    } 
    processItem.Complete(); 
}  
private void ProcessItem(Item myItem) 
{ 
    AddItemToDatabase(myItem); 
    ProcessItemLinks(myItem); 
    ProcessItemComments(myItem); 
}  
private void ProcessItemLinks(Item myItem) 
{ 
    foreach (Item link in myItem.Links) 
    { 
     ProcessItem(link); 
    } 
} 
private void ProcessItemComments(Item myItem) 
{ 
    foreach (Item comment in myItem.Comments) 
    { 
     ProcessItem(comment); 
    } 
} 

यहां स्टैक ट्रेस का शीर्ष भाग है। दुर्भाग्य से मैं इस बिंदु तक निर्माण को अपनी कंपनी संवेदनशील जानकारी के रूप में नहीं दिखा सकता जिसे मैं प्रकट नहीं कर सकता।

at System.Transactions.TransactionState.EnlistPromotableSinglePhase(InternalTransaction tx, IPromotableSinglePhaseNotification promotableSinglePhaseNotification, Transaction atomicTransaction) 
    at System.Transactions.Transaction.EnlistPromotableSinglePhase(IPromotableSinglePhaseNotification promotableSinglePhaseNotification) 
    at System.Data.SqlClient.SqlInternalConnection.EnlistNonNull(Transaction tx) 
    at System.Data.SqlClient.SqlInternalConnection.Enlist(Transaction tx) 
    at System.Data.SqlClient.SqlInternalConnectionTds.Activate(Transaction transaction) 
    at System.Data.ProviderBase.DbConnectionInternal.ActivateConnection(Transaction transaction) 
    at System.Data.ProviderBase.DbConnectionPool.GetConnection(DbConnection owningObject) 
    at System.Data.ProviderBase.DbConnectionFactory.GetConnection(DbConnection owningConnection) 
    at System.Data.ProviderBase.DbConnectionClosed.OpenConnection(DbConnection outerConnection, DbConnectionFactory connectionFactory) 
    at System.Data.SqlClient.SqlConnection.Open() 
+0

आप स्टैक ट्रेस पोस्ट किया जा सका अपवाद का? –

+0

मैंने अनुमति के रूप में अधिकतर ट्रेस जोड़े हैं। उम्मीद है कि यह पर्याप्त है! – Cragly

+0

क्या आप पूरा अपवाद पोस्ट कर सकते हैं? Ex.ToString() के आउटपुट को पोस्ट करें, फिर कुछ भी संवेदनशील करें। मैं सोच रहा हूं कि एक इंनेरएक्सप्शन या दो है या नहीं। –

उत्तर

23

वितरित लेनदेन किए गए मेरे बाल ग्रे समय से पहले ही जाना :)

सामान्य संदिग्धों

  1. फ़ायरवॉल MSDTC ब्लॉक कर रहा है
  2. आपका लेन-देन किसी कारण से बाहर समय है (टाइमआउट को बढ़ाने का प्रयास)
  3. आपके पास वर्तमान लेनदेन
  4. के साथ गड़बड़ कर रहे कोड के शीर्ष पर कहीं और लेनदेन का दायरा है

परीक्षण करें कि MSDTC ठीक काम कर रहा पहली बार में तत्वों की एक छोटी संख्या डालने से

इसके अलावा परीक्षण dtcping जैसे उपकरणों का उपयोग कर रहा है। आपका कोड एक रिकर्सिव लूप में प्रतीत होता है जो बड़ी मात्रा में डेटा संसाधित कर सकता है। हो सकता है कि आप कई प्रश्नों पर चल रहे हों और लेन-देन समय समाप्त हो रहा है।

कभी-कभी सिस्टम। लेनदेन। लेनदेन। वर्तमान में क्या हुआ इसके बारे में कुछ संकेत हैं। इस वैश्विक चर के खिलाफ एक घड़ी जोड़ें

+0

हाँ मेरे बाल गिरने शुरू हो गए हैं! मैं उपर्युक्त सुझावों के साथ कैसे प्राप्त करूं इस पर एक अद्यतन प्रदान करूंगा। – Cragly

+2

+1 "मेरे बालों को भूरे रंग के बने" के लिए +1 .. यह एक सच्ची कहानी है –

+1

टाइमआउट ने मुझे दो बार पकड़ा है। वितरित लेनदेन के बारे में भूलना आसान है, खासकर जब डीबगिंग। यह ध्यान देने योग्य है कि डिफ़ॉल्ट केवल 1 मिनट है। आप इसे अपने ऐप.कॉन्फिग में जोड़कर (उदाहरण के लिए 10 मिनट) बढ़ा सकते हैं - '', या पैरामीटर के रूप में गुज़रना 'लेनदेनस्कोप() 'के लिए – Rhumborl

0

डिफ़ॉल्ट अधिकतम टाइमआउट 10 मिनट है। आप ओवरराइड कर सकते हैं इस machine.config तथापि में है:

<configuration> 
    <system.transactions> 
     <machineSettings maxTimeout="00:00:30" /> 
    </system.transactions> 
</configuration> 

या आप कोड में ओवरराइड कर प्रतिबिंब का उपयोग कर सकते हैं:

private static void OverrideTransactionScopeMaximumTimeout(TimeSpan timeOut) 
    { 

     // 1. create a object of the type specified by the fully qualified name 

     Type oSystemType = typeof(global::System.Transactions.TransactionManager); 

     System.Reflection.FieldInfo oCachedMaxTimeout = oSystemType.GetField("_cachedMaxTimeout", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Static); 

     System.Reflection.FieldInfo oMaximumTimeout = oSystemType.GetField("_maximumTimeout", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Static); 

     oCachedMaxTimeout.SetValue(null, true); 

     oMaximumTimeout.SetValue(null, timeOut); 

     // For testing to confirm value was changed 

     // MessageBox.Show(string.Format(&quot;DEBUG SUCCESS!! &nbsp;Maximum Timeout for transactions is &#39;{0}&#39;&quot;, TransactionManager.MaximumTimeout.ToString())); 

    } 

अधिक जानकारी: https://blogs.msdn.microsoft.com/ajit/2008/06/18/override-the-system-transactions-default-timeout-of-10-minutes-in-the-code/

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