जावा में डेटाबेस कनेक्शन बंद करना


121

मुझे थोड़ी उलझन हो रही है, मैं नीचे http://en.wikipedia.org/wiki/Java_Database_Connectivity से पढ़ रहा था

Connection conn = DriverManager.getConnection(
     "jdbc:somejdbcvendor:other data needed by some jdbc vendor",
     "myLogin",
     "myPassword" );

Statement stmt = conn.createStatement();
try {
    stmt.executeUpdate( "INSERT INTO MyTable( name ) VALUES ( 'my name' ) " );
} finally {
    //It's important to close the statement when you are done with it
    stmt.close();
}

क्या आपको कनेक्शन को बंद करने की आवश्यकता नहीं है? अगर con.close () नहीं होता है तो वास्तव में क्या हो रहा है?

मेरे पास एक निजी वेब ऐप है जिसे मैं बनाए रख रहा हूं जो वर्तमान में या तो फ़ॉर्म को बंद नहीं करता है, लेकिन क्या वास्तव में एक stmt एक है, एक कॉन है, या दोनों है?

साइट रुक-रुक कर चलती रहती है लेकिन सर्वर कहता है कि यह एक डेटाबेस कनेक्शन का मुद्दा है, मेरा संदेह यह है कि इसे बंद नहीं किया जा रहा है, लेकिन मुझे नहीं पता कि अगर कोई बंद करना है।


समापन को संभालने के लिए हमेशा अन्य ड्राइवरों और टेम्पलेट्स के आधार पर, अपने दम पर कनेक्शन बंद करना एक सर्वोत्तम अभ्यास है। कनेक्शन बंद करने की विफलता के परिणामस्वरूप सॉकेट और संसाधन हमेशा के लिए खुले रहेंगे जब तक कि कोई दुर्घटना (कोई अधिक संसाधन परिदृश्य) या पुनरारंभ न हो।
अरुण जोशला

जवाबों:


196

जब आप अपने उपयोग के साथ किया जाता है Connection, तो आपको close()किसी अन्य डेटाबेस संसाधनों (कर्सर, हैंडल, आदि) को जारी करने के लिए स्पष्ट रूप से इसकी विधि को कॉल करके इसे बंद करने की आवश्यकता होती है, जो कनेक्शन पर पकड़ हो सकती है।

वास्तव में, जावा में सुरक्षित पैटर्न आपके ResultSet, Statementऔर Connection(उस क्रम में) एक finallyब्लॉक में है जब आप उनके साथ काम करते हैं, तो कुछ इस तरह है:

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

try {
    // Do stuff
    ...

} catch (SQLException ex) {
    // Exception handling stuff
    ...
} finally {
    if (rs != null) {
        try {
            rs.close();
        } catch (SQLException e) { /* ignored */}
    }
    if (ps != null) {
        try {
            ps.close();
        } catch (SQLException e) { /* ignored */}
    }
    if (conn != null) {
        try {
            conn.close();
        } catch (SQLException e) { /* ignored */}
    }
}

finallyब्लॉक थोड़ा (शून्य की जांच से बचने के लिए) में सुधार किया जा सकता:

} finally {
    try { rs.close(); } catch (Exception e) { /* ignored */ }
    try { ps.close(); } catch (Exception e) { /* ignored */ }
    try { conn.close(); } catch (Exception e) { /* ignored */ }
}

लेकिन, फिर भी, यह अत्यंत क्रियात्मक है इसलिए आप आमतौर पर अशक्त-सुरक्षित सहायक विधियों में वस्तुओं को बंद करने के लिए एक सहायक वर्ग का उपयोग करते हैं और finallyब्लॉक कुछ इस तरह हो जाता है:

} finally {
    DbUtils.closeQuietly(rs);
    DbUtils.closeQuietly(ps);
    DbUtils.closeQuietly(conn);
}

और, वास्तव में, Apache Commons DbUtils में एक ऐसा DbUtilsवर्ग है जो ठीक ही कर रहा है, इसलिए आपको अपना लिखने की कोई आवश्यकता नहीं है।


3
बहुत बढ़िया मदद, धन्यवाद! मैं कॉन के बारे में नहीं सोचता था! = अशक्त कथन।
onaclov2000

1
@ onaclov2000 हाँ, rs, ps, connहो सकता है nullपर जहां कोड टूट जाता है निर्भर करता है। इसलिए इसे "सुरक्षित" पैटर्न के रूप में जाना जाता है।
पास्कल थिवेंट

12
@ पास्कल थिवेंट: वास्तव में हमें उन सभी को बंद करने की आवश्यकता नहीं है। "कोर जावा वॉल्यूम टू - एडवांस्ड फीचर्स" पुस्तक में लिखा गया है: यदि कथन का एक खुला परिणाम सेट है, तो closeकिसी Statementऑब्जेक्ट की विधि स्वचालित रूप से संबंधित को बंद कर देती है ResultSet। इसी तरह, कक्षा की closeविधि Connectionसभी Statementsको बंद कर देती है Connection
माजिद आज़मी

12
@ माजिद: जब तक यह एक जमा कनेक्शन नहीं है। तब बयान लीक हो जाते थे।
BalusC

1
@ बालसु: क्या आप बता सकते हैं कि क्या होता है जब कनेक्शन का उपयोग करके एक बंद कनेक्शन बंद कर दिया जाता है। क्लो () विधि
कृष्ण चैतन्य

61

उपयोग के बाद डेटाबेस / संसाधन ऑब्जेक्ट को बंद करना हमेशा बेहतर होता है। finallyब्लॉक में कनेक्शन, परिणाम और बयान वस्तुओं को बंद करने के लिए बेहतर है ।

Java7 तक, finallyब्लॉक का उपयोग करके इन सभी संसाधनों को बंद करना होगा । यदि आप जावा 7 का उपयोग कर रहे हैं, तो संसाधनों को बंद करने के लिए आप निम्नानुसार कर सकते हैं।

try(Connection con = getConnection(url, username, password, "org.postgresql.Driver");
    Statement stmt = con.createStatement();
    ResultSet rs = stmt.executeQuery(sql);
) {

//statements
}catch(....){}

अब, con, stmt और rs ऑब्जेक्ट्स कोशिश ब्लॉक का हिस्सा बन जाते हैं और जावा उपयोग के बाद इन संसाधनों को स्वतः बंद कर देता है।

आशा है कि मैं मददगार था।


यदि मेरा बयान निहित है, ResultSet rs = conn.createStatement().executeQuery(sql);तो tryब्लॉक के अंदर क्या होगा ?
Antares42

1
आप उन्हें बंद करने के लिए अंततः {} ब्लॉक में संदर्भित नहीं कर पाएंगे। यदि एक अपवाद को फेंक दिया जाता है, तो ResultSet का क्लोज () तरीका कभी भी लागू नहीं होगा
दान

अगर मैं उन्हें बंद नहीं करता तो क्या होता है?
एलेक्स78191

यदि आप उन्हें बंद नहीं करते हैं, तो मेमोरी लीक हो सकती है।
यदु कृष्णन

14

यह सिर्फ Statementऔर सिर्फ बंद करने के लिए पर्याप्त है ConnectionResultSetऑब्जेक्ट को स्पष्ट रूप से बंद करने की कोई आवश्यकता नहीं है ।

जावा प्रलेखन के बारे में कहते हैं java.sql.ResultSet:

एक ResultSet ऑब्जेक्ट स्वचालित रूप से स्टेटमेंट ऑब्जेक्ट द्वारा बंद किया जाता है जो इसे तब उत्पन्न करता है जब स्टेटमेंट ऑब्जेक्ट को बंद कर दिया जाता है, फिर से निष्पादित किया जाता है, या अगले परिणाम को कई परिणामों के अनुक्रम से प्राप्त करने के लिए उपयोग किया जाता है।


धन्यवाद BalusC टिप्पणियों के लिए: "मैं उस पर भरोसा नहीं करेगा। कुछ JDBC ड्राइवर उस पर विफल होते हैं।"


25
मैं उस पर भरोसा नहीं करेगा। कुछ JDBC ड्राइवर उस पर विफल होते हैं। उदाहरण के लिए "अधिकतम खुले कर्सर पार हो गए" के साथ ओरेकल, आदि बस स्पष्ट रूप से सभी खुले संसाधनों को बंद कर देते हैं, कोई बहाना नहीं।
बालुस

1
मैं बल्कि ऐसे ड्राइवरों का उपयोग नहीं करूंगा जो ऐनक के अनुरूप नहीं हैं
Enerccio

2
जैसा कि BalusC बताता है, किसी विशेष प्रदाता पर निर्भरता को हार्ड करने के बजाय कनेक्शन को स्पष्ट रूप से बंद करना अच्छा रक्षात्मक प्रोग्रामिंग है।
माइकल

11

हाँ। आपको परिणाम, विवरण और कनेक्शन को बंद करने की आवश्यकता है। यदि कनेक्शन एक पूल से आया है, तो इसे बंद करना वास्तव में इसे पुन: उपयोग के लिए पूल में भेजता है।

आपको इसे आमतौर पर एक finally{}ब्लॉक में करना होगा , जैसे कि यदि कोई अपवाद फेंका जाता है, तो भी आपको इसे बंद करने का मौका मिलता है।

आपके लिए इस संसाधन आवंटन / सौदे के मुद्दे के बाद कई रूपरेखाएँ दिखाई देंगी। जैसे कि स्प्रिंग का JdbcTemplateApache DbUtils के पास परिणाम देखने के लिए विधियाँ / कथन / कनेक्शन है जो अशक्त है या नहीं (और समापन पर अपवादों को पकड़ना है), जो मदद भी कर सकता है।


1
जब मैं एक "अंत में" ग्रहण सम्मिलित करता हूं, तो मुझे यह बताना गलत लगता है कि यह गलत है। यह पकड़ ब्लॉक के बाद जाना चाहिए?
onaclov2000

हाँ। {} {} पकड़ अंत में कोशिश {}। पकड़ {} वैकल्पिक है, btw। अंत में {} की तरह
ब्रायन एग्न्यू

मैंने अंत में "करीब" बयानों को स्थानांतरित किया, लेकिन वे सिर्फ "sqlexception" कह रहे हैं, कोई सुझाव?
onaclov2000

1
करीब () एक SQLException फेंकता है। आपको उसे संभालना होगा। इसे चुपचाप संभालने के लिए DbUtils.closeQuietly () देखें।
ब्रायन एग्न्यू

> क्या वास्तव में हो रहा है अगर con.close () नहीं होता है?
एलेक्स78191

8

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

आपको ऐसा किसी भी ऑब्जेक्ट के साथ करना चाहिए जो AutoClosable को लागू करता है।

try (Connection connection = getDatabaseConnection(); Statement statement = connection.createStatement()) {
    String sqlToExecute = "SELECT * FROM persons";
    try (ResultSet resultSet = statement.execute(sqlToExecute)) {
        if (resultSet.next()) {
            System.out.println(resultSet.getString("name");
        }
    }
} catch (SQLException e) {
    System.out.println("Failed to select persons.");
}

GetDatabaseConnection के लिए कॉल बस बना है। इसे उस कॉल से बदलें जो आपको JDBC SQL कनेक्शन या पूल से कनेक्शन के साथ मिलती है।


तो आपको इस मामले में मैन्युअल रूप से कनेक्शन बंद करने की आवश्यकता नहीं है?
कॉलिन डी

1
सही बात। आपको कनेक्शन को स्पष्ट रूप से बंद करने की आवश्यकता नहीं है। कोशिश कोड ब्लॉक के अंत तक पहुंचने पर इसे बंद कर दिया जाएगा।
जो

7

हां, आपको कनेक्शन बंद करने की आवश्यकता है। अन्यथा, डेटाबेस क्लाइंट आमतौर पर सॉकेट कनेक्शन और अन्य संसाधनों को खुला रखेगा।


... जब तक यह बाहर नहीं निकलता। यह क्लाइंट और सर्वर साइड पर विभिन्न परिमित संसाधनों को टाई करता है। यदि कोई क्लाइंट इस तरह की बात करता है, तो यह क्लाइंट के लिए समस्याएँ, डेटाबेस सेवा और संभवतः क्लाइंट या सर्वर मशीन पर चलने वाले अन्य अनुप्रयोगों के लिए भी समस्या पैदा कर सकता है।
स्टीफन C
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.