2013-11-01 23 views
7

एप्लिकेशन अपने पिछले question में वर्णित है। दाल तरफ मैं उपयोगओडीपी .NET अजीब व्यवहार करता है

Oracle.ManagedDataAccess, Version=4.121.1.0, Culture=neutral, PublicKeyToken=89b483f429c47342 

यहां कनेक्शन स्ट्रिंग है:

User id=usr;Password=pwd;Data Source=database1;Validate connection=True;Connection timeout=8;Pooling=false 

starange है कि कभी कभी ODP निम्न अपवाद बाहर उठाती है:

Oracle.ManagedDataAccess.Client.OracleException (0xFFFFFC18): Connection request timed out 
    in OracleInternal.ConnectionPool.PoolManager`3.CreateNewPR(Int32 reqCount, Boolean bForPoolPopulation, ConnectionString csWithDiffOrNewPwd, String instanceName) 
    in OracleInternal.ConnectionPool.PoolManager`3.Get(ConnectionString csWithDiffOrNewPwd, Boolean bGetForApp, String affinityInstanceName, Boolean bForceMatch) 
    in OracleInternal.ConnectionPool.OraclePoolManager.Get(ConnectionString csWithNewPassword, Boolean bGetForApp, String affinityInstanceName, Boolean bForceMatch) 
    in OracleInternal.ConnectionPool.OracleConnectionDispenser`3.Get(ConnectionString cs, PM conPM, ConnectionString pmCS, SecureString securedPassword, SecureString securedProxyPassword) 
    in Oracle.ManagedDataAccess.Client.OracleConnection.Open() 
    in MySyncApp.DBRepository.GetChangedDataDB(DateTime startPeriod) in D:\MySyncApp\MySyncApp\DB.cs:line 23 
    in MySyncApp.Program.<>c__DisplayClass30.<>c__DisplayClass32.<Synchronize>b__2f(ID id) in D:\MySyncApp\MySyncApp\Program.cs:line 441 

लेकिन इस अपवाद के बाद, जब मैं ओरेकल में सत्रों को देखें, मुझे लगता है कि वास्तव में कनेक्शन जीवित है और बस INACTIVE के रूप में चिह्नित किया गया है! इसलिए, ऐसे कनेक्शन सर्वर पक्ष पर लटकते रहेंगे, धीरे-धीरे उपलब्ध सत्रों की गिनती समाप्त हो जाएंगे।

मेरी कोड में विशेष कुछ भी नहीं है, बस

public List<DataObj> GetChangedDataDB(DateTime startPeriod) 
{ 
    List<DataObj> list = new List<DataObj>(); 
    using (OracleConnection conn = new OracleConnection(this._connstr)) 
    { 
     conn.Open(); 

     using (OracleCommand comm = new OracleCommand("select data from table(usr.syncpackage.GetChanged(:pStart))", conn)) 
     { 
      comm.CommandTimeout = 10; 
      comm.Parameters.Add(":pStart", startPeriod); 

      using (OracleDataReader reader = comm.ExecuteReader()) 
      { 
       // ..omitted 
      } 
     } 

    } 
    return list; 
} 

इस कोड को एक साथ डेटाबेस का एक बहुत से डेटा बाहर खींचने के लिए Parallel.ForEach पाश में चलाता है। यहां तक ​​कि एक ही डेटाबेस के लिए तीन समांतर कनेक्शन हो सकते हैं (उदाहरण के लिए, स्कीमा के विभिन्न हिस्सों से डेटा खींचें, उदाहरण के लिए, उद्यम के तीन अलग-अलग विभागों से)। 64 बिट उत्पादन

तुल्यकालन प्रक्रिया ही 10 सेकंड के अंतराल में टाइमर पर आग -

ओरेकल

Oracle डाटाबेस 11g एंटरप्राइज़ संस्करण रिलीज 11.2.0.3.0 है। यदि पहले से ही काम तो अगले काम बंद कर दिया जा रहा है को चलाने का है:

public static void Synchronize(object obj) 
    {    
     // ... omitted 
     log.Info("ITERATION_COMMON_START"); 

     if (Program.State == "Running") 
     { 
      log.Info("ITERATION_COMMON_END_BY_EXISTING"); 
      return; 
     } 

     lock (Program.StateLock) 
     { 
      Program.State = "Running"; 
     }     

     Parallel.ForEach(Global.config.dbs, new ParallelOptions { MaxDegreeOfParallelism = -1 }, (l) => 
     { 
      Console.WriteLine("Started synchronization for {0}", l.key); 
      DBRepository db = new DBRepository(l.connectionString); 

      Parallel.ForEach(l.departments, new ParallelOptions { MaxDegreeOfParallelism = -1 }, (department) => 
      {      
       DateTime ChangesFromTS = GetPreviousIterationTS; 
       List<DataObj> cdata = db.GetChangedDataDB(ChangesFromTS); 
       // ... doing the work here 
      } 

     } 

     // Finishing work 

     GC.Collect();    

     lock (Program.StateLock) 
     { 
      Program.State = ""; 
     } 

    } 

यहाँ समय-समय पर सिंक्रनाइज़ कार्यों लागू के लिए टाइमर है:

Program.getModifiedDataTimer = new Timer(Program.Synchronize, null, (int)Global.config.syncModifiedInterval * 1000, (int)Global.config.syncModifiedInterval * 1000); 

Global.config.syncModifiedInterval

ODP ही उसी तरह बर्ताव करता है सेकंड में है जब मैं पूलिंग चालू करता हूं। यह उसी अपवाद के साथ कनेक्शन स्ट्रिंग में Max pool size निर्देश द्वारा अनुमत की तुलना में अधिक कनेक्शन बनाए गए हैं।

कृपया मुझे उस सामान पर अपने विचार और अनुभव बताएं।

(PUB) (ERR) OracleConnection.Open() (txnid=n/a) Oracle.ManagedDataAccess.Client.OracleException (0xFFFFFC18): Connection request timed out 
    in OracleInternal.ConnectionPool.PoolManager`3.CreateNewPR(Int32 reqCount, Boolean bForPoolPopulation, ConnectionString csWithDiffOrNewPwd, String instanceName) 
    in OracleInternal.ConnectionPool.PoolManager`3.Get(ConnectionString csWithDiffOrNewPwd, Boolean bGetForApp, String affinityInstanceName, Boolean bForceMatch) 
    in OracleInternal.ConnectionPool.OraclePoolManager.Get(ConnectionString csWithNewPassword, Boolean bGetForApp, String affinityInstanceName, Boolean bForceMatch) 
    in OracleInternal.ConnectionPool.OracleConnectionDispenser`3.Get(ConnectionString cs, PM conPM, ConnectionString pmCS, SecureString securedPassword, SecureString securedProxyPassword) 
    in Oracle.ManagedDataAccess.Client.OracleConnection.Open() 

अद्यतन # 2

की तरह इस कनेक्शन से पता चलता है लगता है:


अद्यतन

यहाँ ओरेकल ट्रेस का एक टुकड़ा जब अपवाद उठाया है है अप बी अंतराल कनेक्शन स्थापित करने के अनुरोध की तरह अंतराल कनेक्शन की पारिस्थितिकी भेज दी गई है, लेकिन इसकी प्रतिक्रिया को नजरअंदाज कर दिया गया है। या गंतव्य पर जाने पर सर्वर से प्रेषित डेटा दूषित हो रहा है।

कनेक्शन सर्वर के सत्र सूची में फांसी रहता है यहां तक ​​कि जब मैं बंद आवेदन। जब मैं एक सत्र को मारता हूं तो यह "किल्ड" लेबल के साथ सूची में लटक रहा है।


अद्यतन # 3

Here है कि एक ही मुद्दा बना देता है डेमो अनुप्रयोग है। जैसा कि मैंने पहले बताया था, यह खराब कनेक्शन पर दिखाई देता है, आप WANem एमुलेटर का उपयोग करके ऐसे कनेक्शन का अनुकरण कर सकते हैं। Here वही घटक है जो मैं डेटाबेस कनेक्टिविटी के लिए उपयोग करता हूं। आपकी मदद के लिए आशा है।

+0

आप जब ऐसा होता है अपने आवेदन के एक डंप प्रदान कर सकता है? – Olivier

+0

@ ओलिवियर कृपया मेरा तीसरा प्रश्न अपडेट देखें। उम्मीद है कि यह समस्या को पुन: उत्पन्न करना आसान बनाता है। लेकिन हाँ, निश्चित रूप से, मैं एक डंप कर सकते हैं। – kseen

+0

क्या आप कभी इसे हल करने में सक्षम थे? –

उत्तर

4

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

इसके अलावा, मैं प्रलेखन करते हुए कहा कि ODP.net थ्रेड-सुरक्षित नहीं है नहीं मिल सकता है, लेकिन मैं किसी भी प्रलेखन हुए कहा कि यह या तो है, इसलिए यदि कुछ भी नहीं किसी और में मदद करता है इस बदलाव की कोशिश नहीं मिल सकता है:

Parallel.ForEach(Global.config.dbs, new ParallelOptions { MaxDegreeOfParallelism = -1 }, (l) => 
    { 
     Console.WriteLine("Started synchronization for {0}", l.key); 

     Parallel.ForEach(l.departments, new ParallelOptions { MaxDegreeOfParallelism = -1 }, (department) => 
     {      
      // Now local to the executing thread. 
      DBRepository db = new DBRepository(l.connectionString); 

      DateTime ChangesFromTS = GetPreviousIterationTS; 
      List<DataObj> cdata = db.GetChangedDataDB(ChangesFromTS); 
      // ... doing the work here 
     } 

    } 
0

आप क्या कमांड टाइमआउट (विधि GetCangedDataDB विधि में कोड लाइन) को शामिल करने का प्रयास करें? इस

comm.CommandTimeout = 360; 

मैं परियोजना बना लिया है जो एक बहुत बड़ा डेटा का प्रबंधन और मैं भी आप के रूप में त्रुटि संदेश मिला, तो मैं अधिक से अधिक CommandTimeout मूल्य जोड़ने की तरह कुछ है, तो यह काम करता है, लेकिन मुझे लगता है अगर आप यकीन नहीं है मेरे जैसा ही मामला मिला।

अन्य तरह से, मैंने देखा कि आप Parallel.ForEach दायरे में Parallel.ForEach गुंजाइश है, और मुझे लगता है कि आप टास्क समानांतर लाइब्रेरी का उपयोग कर के साथ दूसरे गुंजाइश संशोधित करने के लिए कोशिश कर सकते हैं। आप इसे और अधिक यहाँ सीख सकते http://msdn.microsoft.com/en-us/library/dd537609.aspx

फिर अपने दूसरे Parallel.ForEach गुंजाइश इस

Task task = new Task(() => 
Parallel.ForEach(l.departments, new ParallelOptions { MaxDegreeOfParallelism = -1 }, (department) => 
{ 
    // Now local to the executing thread. 
    DBRepository db = new DBRepository(l.connectionString); 

    DateTime ChangesFromTS = GetPreviousIterationTS; 
    List<DataObj> cdata = db.GetChangedDataDB(ChangesFromTS); 
    // ... doing the work here 
} 
)); //close lambda expression 

task.Start(); 
1

मैं अपने एफ # कोड के साथ एक ही समस्या थी की तरह होना चाहिए। यह एक ही समय में कई कनेक्शन पैदा करता है और कार्य समानांतर लाइब्रेरी का उपयोग नहीं करता है। मैं मानता हूँ flindeberg, Motomoto Pink और अपने खुद के निष्कर्ष के साथ कि समस्या ओरेकल से प्रतिक्रिया confirmatoin कनेक्शन कनेक्शन अनुरोध का समय समाप्त अपवाद के बाद आता है।

के रूप में दूसरों को, मैं तुम्हें कनेक्शन अनुरोध का समय समाप्त बढ़ाने के लिए सुझाव देते हैं। लेकिन additionaly आप Min Pool Size पैरामीटर समानांतर की संख्या के लिए सेट के सिलसिले पूल का उपयोग कर पैदा की धागे जो कनेक्शन खुल जाएगा पर विचार कर सकते हैं। जब कनेक्शन विभागों की संख्या बड़ी होती है तो कनेक्शन पूल का उपयोग क्लाइंट और सर्वर दोनों तरफ प्रदर्शन में काफी वृद्धि कर सकता है।

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