2010-03-02 12 views
21

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

क्या ऐसा करने के लिए एक मानक, स्वीकार्य तरीका है? फर्क पड़ता है क्या? Connection को बंद करने से PreparedStatement बंद हो जाता है, क्योंकि PreparedStatement सीधे Connection ऑब्जेक्ट से संबंधित है?

+1

आपने इसे कहाँ देखा? – BalusC

+0

हालांकि नमूना के अनुसार, कनेक्शन बंद होने पर बयान बंद होना चाहिए, जेडीबीसी ड्राइवरों को इसके साथ समस्याएं दिखाई दे रही हैं, इसलिए इसे कथन (और परिणाम सेट) को स्पष्ट रूप से बंद करने के लिए अच्छा अभ्यास माना जाता है। – Yishai

+0

उलटा क्रम में चीजों को बंद करें आपने उन्हें खोला। सारी चीजें। वास्तव में – EJP

उत्तर

36

बयान। मैं तुम्हें (क्रम में)

  1. परिणाम सेट
  2. बयान
  3. कनेक्शन

(और रास्ते में nulls के लिए जाँच!)

यानी बंद करने के लिए उम्मीद करेंगे शुरुआती अनुक्रम के लिए रिवर्स में बंद करें।

यदि आप वसंत JdbcTemplate (या इसी तरह) का उपयोग करते हैं तो यह आपके लिए इसका ध्यान रखेगा। वैकल्पिक रूप से आप Apache Commons DbUtils और DbUtils.close() या DbUtils.closeQuietly() का उपयोग कर सकते हैं।

+1

। कुछ जेडीबीसी ड्राइवर कनेक्शन बंद होने के बाद परिणाम सेट या कथन बंद करने पर अपवाद फेंक देंगे। – Yishai

+11

यह सही है। बिंदु पर: ** संसाधन * को ** रिवर्स ऑर्डर ** में बंद करें जैसा आपने उन्हें अधिग्रहित किया था। – BalusC

7

निम्नलिखित प्रक्रियाओं से किया जाना चाहिए (क्रम में)

  • ResultSet
  • PreparedStatement
  • Connection

इसके अलावा, finally में बंद होने की गारंटी के करीब सभी जेडीबीसी संबंधित वस्तुओं को बंद करने की सलाह दी जाती है।

//Do the following when dealing with JDBC. This is how I've implemented my JDBC transactions through DAO.... 

Connection conn = null; 
PreparedStatement ps = null; 
ResultSet rs = null; 

try { 
    conn = .... 
    ps = conn.prepareStatement(...); 

    //Populate PreparedStatement 
    rs = ps.executeQuery(); 

} catch (/*All relevant exceptions such as SQLException*/Exception e) { 
    logger.error("Damn, stupid exception: " , e); 
} finally { 
if (rs != null) { 
      try { 
       rs.close(); 
       rs = null; 
      } catch (SQLException e) { 
       logger.error(e.getMessage(), e.fillInStackTrace()); 
      } 
     } 

     if (ps != null) { 
      try { 
       ps.close(); 
       ps = null; 
      } catch (SQLException e) { 
       logger.error(e.getMessage(), e.fillInStackTrace()); 
      } 
     } 

     try { 
      if (conn!= null && !conn.isClosed()){ 
       if (!conn.getAutoCommit()) { 
        conn.commit(); 
        conn.setAutoCommit(true); 
       } 
       conn.close(); 
       conn= null; 
      } 
     } catch (SQLException sqle) { 
      logger.error(sqle.getMessage(), sqle.fillInStackTrace()); 
     } 
} 

आप देख सकते हैं अगर मेरा वस्तुओं बातिल और कनेक्शन के लिए कर रहे हैं देख लिया है, जाँच पहले यदि कनेक्शन autocommited नहीं है। बहुत से लोग इसे जांचने में असफल रहते हैं और महसूस करते हैं कि लेनदेन डीबी के लिए प्रतिबद्ध नहीं है।

+5

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

+0

@Yishai - धन्यवाद, मैं इसके बारे में सोच रहा था। – froadie

+0

@ यिशई, हाँ, मैं यह उल्लेख करना भूल गया कि अगर अपवाद हैं और ऑटोोकॉमिट बंद है, तो आप रोलबैक कर सकते हैं ... इसे दिखाने के लिए धन्यवाद। –

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