डेटाबेस कनेक्शन बनाना - क्या यह एक बार या प्रत्येक क्वेरी के लिए है?


101

जब मेरा वेब पेज पहली बार लोड होता है, तो मैं एक डेटाबेस कनेक्शन बनाता हूं। मैं तब पृष्ठ को संसाधित करता हूं और उस अवधारणा के खिलाफ कोई भी प्रश्न चलाता हूं। क्या यह ऐसा करने का सबसे अच्छा तरीका है या मुझे हर बार एक क्वेरी चलाने के लिए डेटाबेस कनेक्शन बनाना चाहिए?

ps यह मेरे लिए 1 कनेक्शन बनाने और इसका उपयोग करने के लिए अधिक समझ में आता है, लेकिन मुझे नहीं पता कि क्या यह किसी अन्य मुद्दे का कारण बन सकता है।

मैं MSSQL के साथ C # (ASP.NET) का उपयोग कर रहा हूं।

जवाबों:


124

यदि आप प्रति क्वेरी / लेन-देन एक बनाते हैं, तो कनेक्शनों को "बंद करना" प्रबंधित करना बहुत आसान है।

मैं देख सकता हूं कि सामान्य ज्ञान यह क्यों निर्धारित करता है कि आपको एक को खोलना चाहिए और इसे पूरे उपयोग करना चाहिए, लेकिन आप गिराए गए कनेक्शन और मल्टीथ्रेडिंग के साथ समस्याओं में भाग लेंगे। तो आपका अगला कदम एक पूल को खोलना होगा, 50 का कहना है, कनेक्शन और उन सभी को खुला रखना होगा, उन्हें अलग-अलग प्रक्रियाओं से अलग करना होगा। और तब आपको पता चलेगा कि यह वही है जो .NET फ्रेमवर्क आपके लिए पहले से है

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


जब आप इसे पोस्ट कर रहे थे तो बस वह लेख पढ़ रहा था :) धन्यवाद।
वेबनोब

2
आपके द्वारा लिंक किया गया वेबपेज SQL सर्वर के लिए विशिष्ट है। क्या .NET अन्य डेटाबेस जैसे - Oracle, Sqlite, MySql से कनेक्ट होने पर स्वचालित पूलिंग भी प्रदान करता है?
briddums

@briddums - मुझे लगता है कि कनेक्टर पर निर्भर करता है। .Net, उदाहरण के लिए, MySql कनेक्टर प्रदान नहीं करता है। यह MySql द्वारा लिखित और अनुरक्षित है। और जब तक यह काम करता है, मेरे अनुभव में पहले का कार्यान्वयन बग मुक्त था।
ZweiBlumen

1
@briddums: प्रदाता असेंबली पर निर्भर करता है। मुझे यकीन है कि Microsoft का Oracle कार्यान्वयन और Oracle का अपना समर्थन कनेक्शन पूलिंग दोनों है, क्योंकि मैंने उनका उपयोग किया है। मैंने सुना है कि एक MySql एक है जो करता है, और मुझे उम्मीद है कि स्प्रिंगनेट में प्रदाताओं को पूलिंग का समर्थन करना चाहिए, लेकिन आप प्रदाता से सीधे पूछने या मुझसे पूछने से बेहतर हैं।
पीडी

1
यह पता होना चाहिए कि एक लूप को खोलना, एक क्वेरी चलाना, और एक कनेक्शन को निपटाना, यहां तक ​​कि एक लूप में भी उतना ही तेज है, और कभी-कभी एक बार खोलने और क्वेरी को लूप करने की तुलना में तेजी से। हमेशा बस निपटाना। यह अधिक सुरक्षित है, और फास्ट है। पूल से एक कनेक्शन प्राप्त करने के ओवरहेड के बारे में चिंता न करें - यह बहुत तुच्छ है।
smdrager

38

प्रति क्वेरी एक कनेक्शन बनाने के लिए सबसे अच्छा अभ्यास करें - और डेटा प्रदर्शित करने के मामले में, सबसे अच्छा अभ्यास एक बार में सभी आवश्यक डेटा में क्वेरी लाना है ।

पृष्ठभूमि की जानकारी:

.NET में, कॉलिंग SqlConnection.Open()डिफ़ॉल्ट रूप से हमेशा कनेक्शन पूलिंग ( MSDN पर "SQL सर्वर के साथ कनेक्शन पूलिंग का उपयोग करना") का उपयोग करती है । तो आप बस एक नया कनेक्शन का उपयोग कर पकड़ सकते हैं Open(), और Close()जब आप काम कर रहे हों तो कॉल कर सकते हैं और .NET सही काम करेगा।

ध्यान दें कि कनेक्शन पूलिंग के बिना, प्रति क्वेरी एक कनेक्शन बहुत बुरा विचार होगा क्योंकि वास्तविक डेटाबेस कनेक्शन बनाना बहुत महंगा हो सकता है (प्रमाणीकरण, नेटवर्क ओवरहेड आदि), और साथ ही खुले कनेक्शन की संख्या आमतौर पर बहुत सीमित है।


7
@webnoob - चूंकि .NET कनेक्शन पूलिंग का उपयोग करता है, नहीं, यह नहीं है। कारण यह है कि कनेक्शन बंद हो सकते हैं, वास्तविक हो सकते हैं आदि - इसलिए कनेक्शन का पुन: उपयोग करना अच्छा अभ्यास नहीं है।
ओडेड

11
-1 जवाब बल्कि भ्रामक है। प्रति क्वेरी कनेक्शन बनाना एक बहुत बुरा विचार है। आपके लिए शायद इसका मतलब है "कनेक्शन पूल से प्रत्येक क्वेरी के लिए एक नया कनेक्शन प्राप्त करना" - लेकिन यह कनेक्शन बनाने के समान नहीं है ।
स्लेस्के

1
@ स्लेस्के - पीडीआर द्वारा उत्तर से कैसे अलग है?
ओडेड

3
@Oded: आह, मैं देख रहा हूँ। .NET में, कॉलिंग SqlConnection.Open()हमेशा पारदर्शी रूप से कनेक्शन पूलिंग का उपयोग करेगी। तो "एक कनेक्शन खोलें" और "एक पूल से एक कनेक्शन को पुनः प्राप्त करें" के बीच अंतर मौजूद नहीं है। मेरी गलतफहमी। मैंने सवाल में थोड़ा स्पष्टीकरण संपादित करने की स्वतंत्रता ली, और वोट वापस ले लिया।
सलेस्के

2
@ eaglei22 - यह निश्चित रूप से ऐसा करना चाहिए (देखें docs.microsoft.com/en-us/dotnet/framework/data/adonet/… )। सामान्य तौर पर, आप, जितनी जल्दी हो सके पूल के लिए कनेक्शन वापस करने के लिए हालांकि, अगर आप अनुक्रम में प्रश्नों के एक नंबर जारी कर रहे हैं, यह चाहेगा सकता है बेहतर हो एक कनेक्शन पुन: उपयोग करने का सुझाव के रूप में। आपको परीक्षण करने और यह देखने की आवश्यकता होगी कि कौन सा दृष्टिकोण आपके लिए बेहतर है (मुझे नहीं पता कि आप किन मानदंडों का उपयोग करते हैं - दोनों तरीकों की जांच करें और अपने चुने हुए मैट्रिक्स पर प्रभाव देखें)।
ऊदबिलाव

0

याद रखें यह सब .Net पारिस्थितिकी तंत्र के संदर्भ में है।

डेवलपर्स कभी-कभी अपनी कनेक्शन वस्तुओं का फिर से उपयोग करने के लिए अपने कोड को "अनुकूलित" करना चाहते हैं। इस प्रश्न के संदर्भ को देखते हुए, यह लगभग हमेशा एक गलती है।

ADO.Net में एक सुविधा है जिसे कनेक्शन पूलिंग कहा जाता है । जब आप एक नया कनेक्शन ऑब्जेक्ट बनाते हैं और खोलते हैं, तो आप वास्तव में जो कर रहे हैं वह एक पूल से कनेक्शन का अनुरोध कर रहा है। जब आप एक कनेक्शन बंद करते हैं, तो आप इसे पूल में वापस कर देते हैं।

हम कोड में सीधे उपयोग की जाने वाली वस्तुओं को समझना महत्वपूर्ण है: SqlConnection, MySqlConnection, OleDbConnectio, आदि, सभी ADO.Net द्वारा प्रबंधित वास्तविक अंतर्निहित कनेक्शन के चारों ओर केवल रैपर हैं , और ADO.Net वास्तविक कनेक्शन बहुत अधिक "भारी" और अधिक महंगे हैं। एक प्रदर्शन के दृष्टिकोण से। यह इन अंतर्निहित वस्तुएं हैं, जिनमें प्रमाणीकरण, नेटवर्क पारगमन, एन्क्रिप्शन जैसी चिंताएं हैं, और वे चीजें जो आपके द्वारा अपने कोड में वास्तव में दिखाई देने वाली वस्तु में स्मृति की छोटी मात्रा से अधिक हैं।

जब आप अपने कनेक्शन ऑब्जेक्ट का पुन: उपयोग करने का प्रयास करते हैं, तो आप महत्वपूर्ण अंतर्निहित कनेक्शनों को प्रभावी ढंग से प्रबंधित करने के लिए ADO.Net की क्षमता को तोड़ते हैं। आप बहुत बड़ी चीज की कीमत पर छोटी चीज में दक्षता हासिल करते हैं।

किसी एप्लिकेशन या http अनुरोध में कनेक्शन का पुनः उपयोग करना आपको गलती से किसी ऐसी चीज़ को क्रमबद्ध करने के लिए भी बाध्य कर सकता है जो अन्यथा समानांतर में चलने में सक्षम हो सकती है, और एक प्रदर्शन अड़चन बन सकती है। मैंने वास्तविक अनुप्रयोगों में ऐसा होते देखा है।

यहां वेब पेज उदाहरण के मामले में, जहां आप कम से कम केवल एक ही http अनुरोध / प्रतिक्रिया की अवधि के लिए छोटे कनेक्शन रखते हैं, आप अपने अनुरोध पाइपलाइन में कौन से प्रश्न चलाते हैं, और मूल्यांकन करके और भी अधिक दक्षता प्राप्त कर सकते हैं। संभव के रूप में डेटाबेस के लिए कुछ अलग अनुरोध के रूप में उन्हें नीचे (संकेत: आप एक एकल SQL स्ट्रिंग में एक से अधिक क्वेरी सबमिट कर सकते हैं, और उनके बीच स्थानांतरित करने के लिए DataReader.NextResult()अलग-अलग तालिकाओं का उपयोग या जांच कर सकते DataSetहैं)।

दूसरे शब्दों में, किसी एप्लिकेशन के लिए एक कनेक्शन को फिर से उपयोग करने या प्रति क्वेरी एक http बनाम बनाम एक कनेक्शन का उपयोग करने के संदर्भ में सोचने के बजाय, हर बार जब आप डेटाबेस के लिए कॉल करते हैं तो एक कनेक्शन के संदर्भ में सोचें ... प्रत्येक दौर की यात्रा। फिर उन यात्राओं की संख्या को कम करके कनेक्शन की संख्या को कम करने का प्रयास करें। इस तरह आप दोनों लक्ष्यों को पूरा कर सकते हैं।


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

यहां तक ​​कि, हालांकि, आमतौर पर प्रति कनेक्शन (या गोल यात्रा) एक कनेक्शन होना बेहतर है। ऐसे अन्य पैटर्न हैं जिनका उपयोग करके आप उसी बॉयलरप्लेट कोड को फिर से लिखने से बचने में मदद कर सकते हैं। यहाँ एक उदाहरण मुझे पसंद है, लेकिन कई अन्य हैं।


मुझे इस पार्टी के लिए देर हो रही है, लेकिन मुझे लगता है कि यह उत्तर कुछ महत्वपूर्ण बिंदुओं को कवर करता है :)
जोएल कोएहॉर्न
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.