2009-06-29 14 views
8

हमारे पास कुछ क्लाइंट कोड है जो SQL सर्वर सर्वर से बात करने के लिए .NET में SqlConnection क्लास का उपयोग कर रहा है। यह रुक-रुक कर इस त्रुटि के साथ विफल हो रहा है:.NET SqlConnection वर्ग, कनेक्शन पूलिंग और पुन: कनेक्शन तर्क

"ExecuteReader एक खुली और उपलब्ध कनेक्शन की आवश्यकता है कनेक्शन के वर्तमान स्थिति के बंद रहता है।"

"अस्थायी" समाधान प्रक्रिया है, जिसके बाद सब कुछ काम करता है रिबूट करने के लिए है - हालांकि, यह स्पष्ट रूप से असंतोषजनक है।

कोड प्रत्येक डेटाबेस के लिए SqlConnection उदाहरणों का एक कैश रख रहा है।

हम कोड को फिर से लिखना है, लेकिन इससे पहले कि मैं करते हैं, मैं कुछ चीजें जानने की जरूरत करना चाहते हैं:

मेरा पहला सवाल यह है: यह कनेक्ट और SqlConnection वस्तुओं डिस्कनेक्ट बार-बार करने के लिए अक्षम है, या क्या करता है अंतर्निहित लाइब्रेरी हमारी तरफ से कनेक्शन पूलिंग करती है?

// Is this bad/inefficient? 
for(many-times) 
{ 
    using(SQLConnection conn = new SQLConnection(connectionString)) 
    { 
     // do stuff with conn 
    } 
} 

क्योंकि हमारे कोड नहीं ऊपर क्या करता है, क्या लगता है इस समस्या का संभावित कारण है कि कुछ कनेक्शन है कि कनेक्शन का कारण बनता है की "जीवनकाल" के दौरान अंतर्निहित SQLServer डेटाबेस के लिए होता को बंद करना पड़ा है ...

यदि यह पता चला है कि यह "कैश" एसक्यूएलकनेक्शन ऑब्जेक्ट्स के लिए योग्य है, तो सभी त्रुटियों को संभालने का अनुशंसित तरीका क्या है जिसे डेटाबेस में "रीकनेक्ट" करके हल किया जा सकता है। मैं इस तरह के रूप परिदृश्यों के बारे में बात कर रहा हूँ:

  • डेटाबेस ऑफ़लाइन लिया और ऑनलाइन वापस लाया जाता है, लेकिन ग्राहक प्रक्रिया कोई खुला लेनदेन था, जबकि इस
  • हो रहा था डेटाबेस "कट" था, तो "पुन: कनेक्ट "

मुझे लगता है कि एसक्यूएलकनेक्शन पर एक" राज्य "संपत्ति है ... क्या यह पूछने का कोई उचित तरीका है?

अंत में, मैं एक परीक्षण SQLServer उदाहरण पूर्ण पहुँच अधिकार के साथ सेट अप है: कैसे मैं सटीक त्रुटि से उत्पन्न होने के बारे में जा सकते हैं "। ExecuteReader एक खुली और उपलब्ध कनेक्शन की आवश्यकता है कनेक्शन के वर्तमान स्थिति बंद है"

उत्तर

19

नहीं है, यह SqlConnection ऑब्जेक्ट्स बनाने के लिए अक्षम नहीं है और जब आप पूरा कर लें तो उनमें से प्रत्येक को बंद करें। यह करने के लिए बिल्कुल सही बात है। .NET फ्रेमवर्क कनेक्शन पूलिंग को अपना काम करने दें - इसे स्वयं करने की कोशिश न करें। आपको कनेक्शन पूलिंग सक्षम करने के लिए विशिष्ट कुछ भी करने की आवश्यकता नहीं है (हालांकि आप अपनी कनेक्शन स्ट्रिंग में Pooling=false सेट करके इसे अक्षम कर सकते हैं)।

यदि आप कनेक्शन को कैश करने का प्रयास करते हैं तो ऐसी कई चीजें गलत हो सकती हैं। बस कहें :)

+0

जो मैं सुनने की उम्मीद कर रहा था ... इस बारे में कोई विचार कि मैं सही त्रुटि को कैसे पुन: उत्पन्न कर सकता हूं? (बस "सिद्ध" करने के लिए कि मैंने समस्या तय की है)? –

+0

ईमानदार होने के लिए कहना मुश्किल है। यदि आप एकाधिक धागे से एक ही कनेक्शन का उपयोग करने की कोशिश कर रहे हैं, तो यह आसानी से दौड़ की स्थिति हो सकती है। –

+1

कनेक्शन पूलिंग को अक्षम करने के लिए: "पूलिंग = गलत" जोड़ें; कनेक्शन स्ट्रिंग के लिए। – Richard

2

आपको अपनी कनेक्शन स्ट्रिंग पर connection pooling सक्षम करना चाहिए। उस स्थिति में रनटाइम आपके कनेक्शन को 'पूल' में वापस जोड़ देगा, जब आप उन्हें बंद कर देंगे, वास्तव में डिस्कनेक्ट करने की बजाय। जब पूल से 'नया' कनेक्शन निकाला जाता है तो इसे रीसेट किया जाएगा (यानी sp_reset_connection कहा जाता है) फिर आपके एप्लिकेशन को एक ब्रांड नए, ताजा कनेक्शन के रूप में प्रस्तुत किया जाता है। पूल पारदर्शी रूप से ऐसे मामलों को संभाला जा रहा है जैसे कि पूल में निष्क्रिय होने पर कनेक्शन बंद हो।

'स्क्रैच से' नया कनेक्शन बनाने की लागत महत्वपूर्ण है क्योंकि प्रमाणीकरण के लिए क्लाइंट और सर्वर के बीच कई राउंडट्रिप्स की आवश्यकता होती है (प्रमाणीकरण विधि और एसएसएल सेटिंग्स के आधार पर यह 1 मामले में सर्वश्रेष्ठ मामले बनाम 1 राउंडट्रिप हो सकता है और भी बुरा)।

और अपने प्रश्न का उत्तर देने के लिए, कनेक्शन OnStateChange ईवेंट बढ़ाता है जब उनका राज्य बदलता है, लेकिन यदि आप पूलिंग का उपयोग करते हैं तो आपको इसकी परवाह नहीं करनी चाहिए।

+0

कनेक्शन पूलिंग डिफ़ॉल्ट है, आपको इसे सक्षम करने के लिए कुछ भी करने की आवश्यकता नहीं है। आप इसे अक्षम कर सकते हैं, लेकिन वे एक दुर्लभ आवश्यकता है। – Richard

+1

कृपया सावधान रहें कि यदि आपके पास कनेक्शन पूलिंग सक्षम है और आप यह जांचने के लिए कनेक्शन खोलते हैं कि डेटाबेस मौजूद है या नहीं, और फिर इस जानकारी के आधार पर डेटाबेस बनाएं। फिर sp_reset_connection चाल आपको डेटाबेस देखने में सक्षम नहीं करेगी। तो कनेक्शन पूलिंग के बिना पहला कनेक्शन करें। –

1

मेरी हाल ही में अनुभव में अगर आप इस कोड का उपयोग करें:

using(SQLConnection conn = new SQLConnection(connectionString)) 
{ 
    // do stuff with conn 
} 

एक त्रुटि है, और स्पष्ट रूप से कनेक्शन, यह बंद नहीं किया जाएगा या पूल में वापस जाँच बंद नहीं करते। तो कनेक्शन को बंद करने के लिए कैच या आखिरकार ब्लॉक का उपयोग करें

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