2008-10-29 10 views
12

Connection.close()SqlException फेंकने पर अपवादों को फेंकना चाहिए, लेकिन मैंने हमेशा यह माना है कि किसी भी अपवाद को अनदेखा करना सुरक्षित है (और मैंने कभी ऐसा कोड नहीं देखा है जो उन्हें अनदेखा नहीं करता है)।क्या मुझे java.sql.Connection

आम तौर पर मैं लिखने होगा:

try{ 
    connection.close(); 
}catch(Exception e) {} 

या

try{ 
    connection.close(); 
}catch(Exception e) { 
    logger.log(e.getMessage(), e); 
} 

सवाल यह है:

  1. यह बुरा व्यवहार है (और किसी को भी समस्या नहीं थी जब ऐसे अपवादों अनदेखी है)।
  2. जब Connection.close() कोई अपवाद फेंक देता है।
  3. यदि यह बुरा है तो मुझे अपवाद को कैसे संभालना चाहिए।

टिप्पणी:

मुझे पता है कि अपवाद को त्यागकर बुराई है, लेकिन मैं जब एक कनेक्शन बंद करने फेंका अपवाद को केवल reffering हूँ (और के रूप में मैंने देखा है यह इस मामले में काफी आम है)।

क्या किसी को पता है कि Connection.close() कुछ भी फेंक सकता है?

+0

मैंने हमेशा उन्हें अनदेखा किया है, यह देखते हुए कि इस बिंदु पर मैं डेटाबेस के साथ आमतौर पर कैसे किया जाता हूं। – Powerlord

+0

खाली पकड़ ब्लॉक बुरा हैं। फायरिंग के लायक की तरह। और फायरिंग से, मेरा मतलब है कि हिस्सेदारी पर जल रहा है। यहां तक ​​कि एक साधारण लॉग स्टेटमेंट पर्याप्त होगा, लोग! – erickson

+1

जिनके पास 3 बजे उत्पादन के मुद्दे होने पर कॉल करने के लिए सूची के शीर्ष पर खाली पकड़ने वाले वक्तव्य "स्वयंसेवक" automaticaly हैं। –

उत्तर

10

दरअसल, आप जो कर रहे हैं वह है (लगभग) सर्वोत्तम अभ्यास :-) यहां मैंने वसंत के JdbcUtils.java में देखा है। तो, आप एक और कैच ब्लॉक जोड़ना चाहेंगे।

/** 
* Close the given ResultSet and ignore any thrown exception. 
* This is useful for typical finally blocks in manual code. 
* @param resultSet the ResultSet to close 
* @see javax.resource.cci.ResultSet#close() 
*/ 
private void closeResultSet(ResultSet resultSet) { 
    if (resultSet != null) { 
    try { 
     resultSet.close(); 
    } 
    catch (SQLException ex) { 
     logger.debug("Could not close ResultSet", ex); 
    } 
    catch (Throwable ex) { 
     // We don't trust the driver: It might throw RuntimeException or Error. 
     logger.debug("Unexpected exception on closing ResultSet", ex); 
    } 
    } 
} 
12

आम तौर पर, लोगों ने इस तरह के अपवादों को दूर करने वाले लोगों द्वारा बर्बाद कर दिए हैं।

मेरा सुझाव है अपवादों के साथ कुछ बुनियादी नियमों का पालन:

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

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

यदि आपको कोई भी तरीका दिखाई नहीं देता है तो चेक अपवाद फेंक दिया जा सकता है, इसे पकड़ें और इसे एक अनचेक अपवाद के रूप में फिर से फेंक दें।

यदि आप जानते हैं कि अपवाद का कारण क्या है, तो इसे पकड़ें और ठीक से लॉग इन करें, आपको इस मामले में एक स्टैक ट्रेस की ज़रूरत नहीं है यदि आप इस बात के बारे में बहुत स्पष्ट हैं कि इसका क्या कारण है (और आप कक्षा का उल्लेख कर सकते हैं अगर आप लॉग 4j या कुछ का उपयोग नहीं कर रहे हैं तो यह लॉगिंग कर रहा है।

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

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

बहुत से लोगों ने इस तथ्य पर टिप्पणी की है कि मैंने कहा है कि उन्हें छुपाएं कभी-कभी ठीक है।विशिष्ट होना करने के लिए, एक मामले मैं के बारे में सोच सकता है:

try { 
    Thread.sleep(1000); 
catch (InterruptedException e) { 
    // I really don't care if this sleep is interrupted! 
} 

मुझे लगता है मुख्य कारण मुझे लगता है इस का उपयोग ठीक है, क्योंकि InterruptedException के इस प्रयोग पहली जगह में जाँच अपवाद प्रतिमान का दुरुपयोग है, यह अपवाद की स्थिति को इंगित करने से अधिक नींद के परिणाम को संचारित कर रहा है।

यह भी बहुत कुछ समझ में बनाया होता है करने के लिए:

boolean interrupted=Thread.sleep(1000); 

लेकिन वे अपने नए जाँच अपवाद प्रतिमान पर बहुत गर्व जब वे पहली बार जावा बनाया थे (जाहिर है ऐसा है, तो यह वास्तव में अवधारणा में साफ है - केवल विफल रहता है अभ्यास में)

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

+0

अपवाद को अनदेखा करना कभी भी अच्छा विचार नहीं है, भले ही आप टिप्पणी क्यों करें। अपवाद लॉगिंग करने के लिए न्यूनतम ओवरहेड है, और यह न्यूनतम है जो किया जाना चाहिए, क्योंकि आप "... निश्चित रूप से सुनिश्चित करें कि आप कभी भी कोई समस्या नहीं पैदा करेंगे ...", समस्याएं बाद में नहीं होतीं। –

+0

इसके लिए मेरा सबसे बड़ा मामला नींद है() यह एक चेक अपवाद फेंकता है जो अधिकतर कभी नहीं पहुंचा जा सकता है, और यदि यह पहुंचा जाता है, तो कौन परवाह करता है? अगर मुझे परवाह है (ज़ाहिर है), मैं इसे संभाल लूंगा। लेकिन फिर भी, टिप्पणी करें। –

+0

मैंने एक बार एक ऐसी प्रणाली पर काम किया जो दबाने वाले प्रयासों से घिरा हुआ था, और अधिकांश लोगों के साथ टिप्पणी की गई "यह कभी नहीं होना चाहिए"। वे सही हैं, त्रुटियां कभी नहीं होनी चाहिए, लेकिन वे करते हैं। मैंने जो सबक सीखा, कभी अपवाद को दबाएं। अनिवार्य रूप से वे होते हैं। – Jeremy

3

मुझे व्यक्तिगत रूप से त्रुटि को कम से कम लॉगिंग करने का आपका दूसरा विचार पसंद है। चूंकि आप अपवाद को पकड़ रहे हैं, सैद्धांतिक रूप से एसक्यूएल अपवाद के अलावा कुछ और पकड़ना संभव है। मुझे यकीन नहीं है कि क्या हो सकता है या कितना दुर्लभ (स्मृति अपवादों से बाहर, आदि) लेकिन सभी त्रुटियों को दबाकर मुझे सही नहीं लगता है।

यदि आप त्रुटियों को दबाना चाहते हैं, तो मैं केवल इतना विशिष्ट लोगों के लिए ऐसा करूंगा जो आपको पता है कि इस तरह से संभाला जाना चाहिए।

हाइपोथेसियल स्थिति: क्या होगा यदि आपके एसक्यूएल के पास खुले लेनदेन थे, और कनेक्शन को बंद करने के कारण एक सिवाय इसके कारण, क्या आप उस त्रुटि को दबाना चाहते हैं? यहां तक ​​कि SQLExceptions को दबाकर थोड़ा खतरनाक हो सकता है।

1

आपको अपवाद को संभालना होगा। यह एक बुरा अभ्यास नहीं है। कल्पना करें कि आपने डाटाबेस कनेक्शन बंद करने से पहले नेटवर्क खो दिया था। यह शायद अपवाद फेंक देगा।

क्या यह दुर्लभ है? हाँ। मुझे लगता है कि उन्हें अपवाद कहा जाता है और यह अनदेखा करने का कोई कारण नहीं है। याद रखें कि अगर यह असफल हो सकता है, तो यह असफल हो जाएगा।

आपको इस बारे में भी सोचना चाहिए कि इस बिंदु पर एक शून्य कनेक्शन होना संभव है (यह एक NullPointerException का कारण होगा) या नहीं।

if (connection != null) { 
    try { 
     connection.close(); 
    } catch (SQLException sqle) { 
     logger.log(e.getMessage(), e); 
    } 
} 
0

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

इसके अलावा, यदि आप सही लॉगिंग फ्रेमवर्क का उपयोग कर रहे हैं, तो अपवाद का शून्य या न्यूनतम प्रदर्शन प्रभाव होगा।

1

एक आदर्श दुनिया में, आप एक अपवाद पर कुछ भी नहीं कभी नहीं करना चाहिए, ज़ाहिर है, एक आदर्श दुनिया में, आप एक अपवाद या तो 8)

तो, आप के प्रभावों की जांच के लिए कभी नहीं मिलेगा विभिन्न विकल्प

केवल लॉग इन करें: डेटाबेस संचालन पूरा हो गया है, कुछ भी करने के लिए बाकी नहीं है लेकिन संसाधनों को साफ करें। यदि इस बिंदु पर कोई अपवाद होता है, तो संभवतः इस काम पर कोई प्रभाव नहीं पड़ता है, इसलिए त्रुटि लॉगिंग पर्याप्त होनी चाहिए। बेशक, अगर लॉगिंग के दौरान कोई त्रुटि होती है, तो आपको मूल रूप से विफल डेटाबेस ऑपरेशन को संभालना होगा जो असफल नहीं हुआ था।

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

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

बेशक राय अलग-अलग होंगे।

6

बहुत कम से कम, हमेशाहमेशाहमेशा लॉग अपवाद है कि आप को पकड़ने रहे हैं और पर अभिनय नहीं।

चुपचाप पकड़े गए अपवाद जो सबसे छोटे पेप के बिना निगल गए हैं सबसे खराब हैं।

+1

मुझे विश्वास है कि ऐसा करने के मूल्य को देखने से पहले आपको इस तरह के कोड को डीबग करना होगा। –

0

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

1

तुम भी एक RuntimeException फेंक सकता है:

try { 
    connection.close(); 
} catch(Exception e) { 
    throw new RuntimeException(e); 
} 

आप अपने विधि हस्ताक्षर बदलने की जरूरत नहीं होगी और अपवाद उपयोग करने के लिए सक्षम हो जाएगा। समस्या का कारण खोजने के लिए बाद में विधि प्राप्त करें।

+0

यह बहुत से अपवादों के लिए वास्तव में एक अच्छा समाधान है। मुझे यकीन नहीं है कि आप इसके लिए क्यों मतदान कर रहे थे, मैंने इसे आपके लिए तय किया :) अभ्यास में आप शायद इसे फिर से चलाने के लिए एक और विशिष्ट रनटाइम अपवाद बनाना चाहते हैं। –

+0

इसे रनटाइम अपवाद के रूप में फेंकने का क्या कारण है? – DMKing

+0

हमेशा _reason_ आप संदेश के रूप में लपेट रहे हैं और rethrowing क्यों शामिल हैं। याद रखें, आपके पास स्टैक ट्रेस में जितनी अधिक जानकारी है, उस व्यक्ति को यह समझने की कोशिश कर रहा है कि क्या हुआ। विशेष रूप से यदि वह व्यक्ति कोड से परिचित नहीं है। –

1

ध्यान दें कि Apache Commons DButils एक closeQuietly() तरीका प्रदान करता है, कि आप 'निरर्थक' कैच के साथ अपने कोड को अव्यवस्थित से बचने के लिए उपयोग कर सकते हैं। नोट मैं अपवादों को निगलने की वकालत नहीं कर रहा हूं, लेकिन इस close() परिदृश्य के लिए मुझे लगता है कि यह आमतौर पर स्वीकार्य है।

+0

बंद करने की उचित त्रुटि हैंडलिंग वास्तव में कठिन है सही। –

0

यदि आप इसे संभाल सकते हैं, तो ऐसा करें (और अगर यह अप्रत्याशित था तो इसे लॉग करें)। यदि आप इसे संभाल नहीं सकते हैं, तो इसे ठीक से पुनर्स्थापित करें ताकि उपरोक्त कुछ कोड इसे संभाल सकें।

चुपचाप निगलने वाले व्यक्ति कोड को ठीक करने के लिए व्यक्ति के लिए महत्वपूर्ण जानकारी छोड़ रहे हैं।

0

डेटाबेस से कनेक्शन बंद करने के समय अपवाद को संभालने का यह एक बेहतर अभ्यास है। क्योंकि, बाद में आपके कोड में कुछ समय, यदि आप कथन या परिणाम ऑब्जेक्ट तक पहुंचने का प्रयास कर रहे हैं तो यह स्वचालित रूप से अपवाद उठाएगा। तो, अपवाद को संभालने के लिए बेहतर है।