"खुला / बंद" SqlConnection या खुला रखें?


121

मेरे पास अपने बिजनेस-लॉजिक को स्टैटिक विधियों के साथ सरल स्टेटिक कक्षाओं में लागू किया गया है। इनमें से प्रत्येक विधि खोलने पर SQL कनेक्शन खुलता है / बंद होता है:

public static void DoSomething(string something)
{
    using (SqlConnection connection = new SqlConnection("..."))
    {
        connection.Open();

        // ...

        connection.Close();
    }
}

लेकिन मुझे लगता है कि कनेक्शन खोलने और बंद करने से बचें प्रदर्शन को बचाता है । मैंने OleDbConnection class (SqlConnection के बारे में निश्चित नहीं) के साथ कुछ समय पहले loooong परीक्षण किया था , और यह निश्चित रूप से इस तरह काम करने में मदद की (जहाँ तक मुझे याद है):

//pass the connection object into the method
public static void DoSomething(string something, SqlConnection connection)
{
    bool openConn = (connection.State == ConnectionState.Open);
    if (!openConn)
    {
        connection.Open();
    }

    // ....

    if (openConn) 
    {
        connection.Close();
    }
}

तो प्रश्न है - क्या मुझे विधि (ए) या विधि (बी) चुननी चाहिए? मैं एक और स्टैकओवरफ़्लो प्रश्न पर पढ़ता हूं कि कनेक्शन पूलिंग ने मेरे लिए प्रदर्शन को बचाया, मुझे बिल्कुल परेशान नहीं होना पड़ेगा ...

पुनश्च। यह एक ASP.NET ऐप है - कनेक्शन केवल एक वेब-अनुरोध के दौरान मौजूद है। जीत-ऐप या सेवा नहीं।


1
बस एक सलाह: सीधे DbConnection.StateChangeकनेक्शन की जांच करने के बजाय कनेक्शन के राज्य परिवर्तन (और स्थानीय रूप से स्टोर किया जा सकता है) में परिवर्तनों की निगरानी के लिए घटना का उपयोग करें DbConnection.State। यह आपको प्रदर्शन लागत बचाएगा।
13

1
एक विवरण जो गायब है वह यह है कि यह विधि पृष्ठ अनुरोध का हिस्सा कैसे है। क्या यह एकमात्र विधि कहलाती है या यह है, जैसा कि मैंने अपनी प्रतिक्रिया में मान लिया है, कई तरीकों में से एक को एक पृष्ठ में पुकारा जाता है, यह प्रभावित करता है कि कौन सा उत्तर सही है?)
डेविड मोर्टेंसन

डेविड - इस तरह के तरीकों के बहुत सारे कहा जा रहा है :)
एलेक्स

1
केस ए डिस्पोज़ में विश्वास की कमी दर्शाता है: देखें stackoverflow.com/questions/1195829/… और MSDN msdn.microsoft.com/en-us/library/…
user2864740

जवाबों:


82

एक विकल्प के लिए छड़ी

कनेक्शन पूलिंग आपका मित्र है।


37
IMHO - वह भी बंद करना चाहिए। निपटान यह करेगा।
रॉय नामी

2
@RoyiNamir मैं कनेक्शन बंद करने के लिए कॉल की तरह। विशेष रूप से शुरुआती और नए लोगों के लिए एक कोड आधार के लिए। यह अधिक स्पष्ट और पठनीय है।
25'14

27
@edhedges दोनों का उपयोग करके "बंद" और बंद () अंततः केवल नए लोगों के लिए भ्रम पैदा करने वाला है। वे "उपयोग" करने के उद्देश्य को समझने वाले नहीं हैं। इसके बजाय "बंद करें" का उपयोग न करें, उन्हें "उपयोग" करने का उद्देश्य सिखाएं। ताकि वे सीख सकें कि वे बेहतर हों और वे जो कुछ सीखते हैं उसे कोड के अन्य भागों में लागू करें।
लुइस पेरेज़

1
क्या "ओपन ()" को बुलाया जाना चाहिए? मैं वर्तमान में इसे इस तरह से उपयोग कर रहा हूं: (var con = GetConnection ()) {} public SqlConnection GetConnection () {नया SqlConnection (_connectionString) लौटाएं; }
गांडर्स

79

हर बार मेथड (ए) का प्रयोग करें। जब आप अपने आवेदन को मापना शुरू करते हैं, तो तर्क जो राज्य के साथ व्यवहार करता है, यदि आप नहीं करते हैं तो वास्तविक दर्द बन जाएगा।

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


33

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

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

हालाँकि आप यहां हाथ से काम कर रहे हैं, इसलिए आप ऐसे टूल की जांच कर सकते हैं जो आपके लिए कनेक्शन का प्रबंधन करते हैं, जैसे डेटासेट, लाइनक टू एसक्यूएल, एंटिटी फ्रेमवर्क या NHibernate।


आपको प्रत्येक पृष्ठ कॉल के लिए केवल एक बार प्रत्येक विधि कॉल के भीतर किसी कनेक्शन को खोलना और बंद नहीं करना चाहिए। थॉट्स जो मैंने कम से कम सीखा है;) लागत समय को खोलना और बंद करना।
डेविड मैर्टेन्सन

8
जब आप SqlConnection.Open कहते हैं तो @ डेविड मार्टेंसन - कनेक्शन वास्तव में खोला और बंद नहीं किया जाता है। ASP.NET पूल से सक्रिय कनेक्शन को रीसायकल करता है जब कनेक्शन स्ट्रिंग पहले से उपयोग किए गए कनेक्शन स्ट्रिंग से मेल खाती है। इसमें शामिल ओवरहेड असंगत है, और इसके अलावा, "इसे स्वयं करने की कोशिश" का अर्थ है कि आपको यह सुनिश्चित करने के सभी प्रबंधन कार्यों को मानना ​​होगा कि कनेक्शन अभी भी प्रत्येक बाद के उपयोग के लिए सक्रिय है, जो जटिलता और उपरि जोड़ता है। कनेक्शन पूलिंग के साथ, हर उपयोग के लिए इसे खोलने और बंद करने का सबसे अच्छा अभ्यास है।
जेमी ट्रेवेरी

2
मेरे सभी सम्मान के साथ, "हमेशा करीबी कनेक्शन" का उत्तर प्रश्न को बहुत अच्छी तरह से फिट नहीं करता है ... मैं उन्हें बंद कर देता हूं। सवाल है - कब।
एलेक्स

@ डेविड मार्टेंसन "एक बार प्रत्येक पृष्ठ के लिए" की देखरेख की जाती है। आप सही हैं कि यदि आपके पास एक के बाद एक निष्पादित करने के लिए कई डेटाबेस कमांड हैं, तो आप उन्हें निष्पादित करते समय कनेक्शन को खुला रख सकते हैं। यदि आप बंद और फिर से खोलते हैं तो एक मामूली ओवरहेड होगा - कनेक्शन पूल में जाएगा और इसे एक क्षण बाद से पुनर्प्राप्त किया जाएगा।
कंक्रीट गनेट

1
@ डेविड मार्टेंसन लेकिन कभी भी बेकार का संबंध न रखें। यदि आप उपयोगकर्ता से या किसी अन्य चीज़ के लिए प्रतीक्षा कर रहे हैं, तो इसे बंद करें। यदि संदेह है, तो इसे बंद करें। आप देर से खोलते हैं जैसे आप इस उम्मीद में कर सकते हैं कि किसी और ने कनेक्शन के साथ समाप्त किया है और इसे जमा किया है। फिर आप एहसान लौटाते हैं - जितना जल्दी हो सके उतना करीब।
कंक्रीट गनेट

13

डिस्क्लेमर: मुझे पता है कि यह पुराना है, लेकिन मुझे इस तथ्य को प्रदर्शित करने का एक आसान तरीका मिल गया है, इसलिए मैं अपने दो सेंट के मूल्य में डाल रहा हूं।

यदि आपको यह विश्वास करने में परेशानी हो रही है कि पूलिंग वास्तव में तेज़ होने जा रही है, तो इसे आज़माएं:

निम्नलिखित को कहीं जोड़ें:

using System.Diagnostics;
public static class TestExtensions
{
    public static void TimedOpen(this SqlConnection conn)
    {
        Stopwatch sw = Stopwatch.StartNew();
        conn.Open();
        Console.WriteLine(sw.Elapsed);
    }
}

अब सभी कॉल को अपने प्रोग्राम के Open()साथ बदलें TimedOpen()और चलाएं। अब आपके पास प्रत्येक अलग कनेक्शन स्ट्रिंग के लिए, कंसोल (आउटपुट) विंडो में एक एकल लंबे समय तक चलने वाला और बहुत ही एक गुच्छा होगा तेजी से खुलता है।

यदि आप उन्हें लेबल करना चाहते हैं तो आप new StackTrace(true).GetFrame(1) +कॉल में जोड़ सकते हैं WriteLine


9

भौतिक और तार्किक कनेक्शन के बीच अंतर हैं। DbConnection एक तरह का तार्किक कनेक्शन है और यह Oracle के लिए अंतर्निहित भौतिक कनेक्शन का उपयोग करता है। DbConnection को बंद / खोलना आपके प्रदर्शन को प्रभावित नहीं करता है, लेकिन आपके कोड को साफ और स्थिर बनाता है - इस मामले में कनेक्शन लीक असंभव है।

आपको उन मामलों के बारे में भी याद रखना चाहिए जब db सर्वर पर समानांतर कनेक्शन की सीमाएँ होती हैं - इस बात को ध्यान में रखते हुए कि आपके कनेक्शन को बहुत कम करना आवश्यक है।

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


हाँ, कनेक्शन कनेक्शन नहीं है - यानी DbConnection भौतिक कनेक्शन नहीं है। DbConnection एक .NET क्लास है जो अंतर्निहित शारीरिक कनेक्शन में हेरफेर करने के लिए तरीके और गुण प्रदान करता है।
कंक्रीट गनेट

दुर्भाग्य से यह तुरंत स्पष्ट नहीं था कि यह सब स्पष्ट रूप से किया गया था, लेकिन प्रलेखन इस पर विस्तृत है। docs.microsoft.com/en-us/dotnet/framework/data/adonet/…
Austin Salgat

2

आम तौर पर आपको प्रत्येक लेनदेन के लिए एक कनेक्ट रखना चाहिए (कोई समानांतर गणना नहीं)

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

भले ही ado.net का कनेक्शन पूल हो, डिस्पैच कनेक्शन की लागत बहुत कम है, लेकिन पुन: उपयोग कनेक्शन अधिक बेहतर विकल्प है।

आवेदन में केवल एक ही कनेक्शन क्यों न रखें

क्योंकि जब आप कुछ क्वेरी या कमांड निष्पादित करते हैं तो कनेक्शन अवरुद्ध हो जाता है, तो इसका मतलब है कि आपका आवेदन केवल sametime पर एक db ऑपरेशन कर रहा है, यह कितना खराब प्रदर्शन है।

एक और मुद्दा यह है कि आपके एप्लिकेशन में हमेशा एक कनेक्शन होगा, भले ही आपका उपयोगकर्ता सिर्फ इसे खोल रहा हो, लेकिन कोई संचालन नहीं। यदि आपके आवेदन को खोलने के लिए कई उपयोगकर्ता हैं, तो db सर्वर जल्द ही अपने सभी कनेक्शन स्रोत का खर्च उठाएगा, जबकि आपके उपयोगकर्ताओं ने ऐसा नहीं किया है। कुछ भी।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.