2016-01-02 11 views
6

मान लें कि हमारे पास एक कक्षा है जो डेटाबेस में एक लॉग संदेश लिखती है। इस वर्ग को कोड के विभिन्न हिस्सों से बुलाया जाता है और बार-बार एक ही INSERT कथन निष्पादित करता है। ऐसा लगता है कि एक प्रीपेडस्टेटमेंट का उपयोग करने के लिए बुला रहा है।तैयार किए गए स्टेटमेंट का सही उपयोग

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

अब, यदि इस परिदृश्य में प्रीपेयरस्टेटमेंट का उपयोग करके लाभ प्राप्त करने का एकमात्र तरीका क्लास सदस्य के रूप में इसे खोलना है, तो क्या उसी कनेक्शन में अलग-अलग तैयार किए गए स्टेटमेंट (अलग-अलग प्रश्नों के साथ) एक ही समय में खोला जा सकता है? क्या होता है जब इनमें से दो तैयार किए गए स्टेटमेंट एक ही समय में निष्पादित होते हैं? क्या जेडीबीसी चालक तैयार किए गए स्टेटमेंट के निष्पादन को कतार में डालता है?

अग्रिम धन्यवाद, दानी।

+2

यह आपके द्वारा उपयोग किए जा रहे डीबीएमएस पर निर्भर करता है। कुछ सर्वर पर कुछ (स्वचालित रूप से) कैश निष्पादन योजनाएं करते हैं। कुछ ड्राइवरों में योजनाओं को कैश करते हैं, कुछ –

+0

पिछली टिप्पणी के अलावा, मिडलवेयर भी कथन कैश करने में सक्षम है (जैसे एप्लिकेशन सर्वर)। –

+1

जेडीबीसी कनेक्शन सामान्य रूप से थ्रेड-सुरक्षित नहीं हैं, इसलिए आपको एक ही कनेक्शन पर एक ही समय में (अलग-अलग धागे से) दो तैयार किए गए स्टेटमेंट निष्पादित करने की कोशिश नहीं करनी चाहिए। यदि आप कोशिश करते हैं तो आपको अजीब त्रुटियां मिलेंगी। – Jesper

उत्तर

3

मुझे पता है और अनुभवी, बयान एक कनेक्शन पर समानांतर में नहीं चलते हैं। और जैसा कि आपने सही ढंग से देखा है, PreparedStatement एस Connection पर बनाए गए हैं, जिन्हें वे बनाए गए थे।

जैसा कि आप शायद अपने लॉगिंग कॉल को सिंक्रनाइज़ नहीं करना चाहते हैं (एक बार एक लॉकिंग ओवरहेड में एक डालने), आपको कनेक्शन को इस लॉगिंग स्टेटमेंट के लिए आरक्षित रखना होगा।

लेकिन केवल एक कथन के लिए एक समर्पित पूल होने से बहुत अपमानजनक लगता है - वह भी ऐसा नहीं करना चाहता।

तो कौन से विकल्प शेष हैं?

  • प्रत्येक सम्मिलन के लिए विवरण तैयार करें। चूंकि आपके पास डीबी को डेटा भेजने के लिए I/O ऑपरेशंस होंगे, इसलिए तैयारी का ओवरहेड अपेक्षाकृत छोटा है।

  • एक नया कनेक्शन बनाने के बाद अपने पूल के अंदर बयान तैयार करें और बाद में संदर्भित करने के लिए Map <Connection,PreparedStatement> बनाएं। नए कनेक्शन को थोड़ा धीमा बनाता है लेकिन कथन को रीसायकल करने की अनुमति देता है।

  • अपने लॉग (JMS) क़तार में कुछ async तरह से प्रयोग करें और संदेश प्रेरित सेम अंदर बैच या इसी तरह

शायद कुछ और विकल्प के रूप में सम्मिलित करते हैं - लेकिन यह है कि सब मैं की अभी सोच सकता है ।

इसके साथ शुभकामनाएँ।

+0

हाय जान। आपके उत्तर के लिए Tks।मुझे लगता है कि मैं आपके पहले विकल्प, प्रत्येक कॉल के लिए एक प्रीपेडस्टेटमेंट (मेरे वर्तमान कार्यान्वयन) के साथ रहूंगा, बस मुझे तैयार किए गए स्टेटमेंट की आवश्यकता नहीं दिखाई देगी। मुझे लगता है कि एक सरल वक्तव्य में पूरी क्वेरी को निष्पादित करना जल्द से जल्द होना चाहिए। यदि डीबीएमएस तैयार किए गए स्टेटमेंट को कैश कर रहा है तो इसे किसी भी तरह से बार-बार स्टेटमेंट कैश करना चाहिए। –

+0

काफी विपरीत। यदि आप अपने मूल्य स्ट्रिंग में डालते हैं तो कथन कभी दोहराना नहीं होगा। यह बाइंड वैरिएबल (= प्रीपेडस्टेटमेंट) का उपयोग करके करेगा जो एसक्यूएलएनजेक्शन का उल्लेख नहीं करता है जो हो सकता है यदि आप अपने ऐप के बाहर से "लॉग" स्ट्रिंग्स – Jan

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

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