2012-02-13 8 views
35

कनेक्शन बनाने/प्राप्त करने के सामान्य जेडीबीसी मुहावरे को एकीकृत करने, डेटाबेस से पूछताछ और संभावित रूप से जावा 7 के स्वचालित संसाधन प्रबंधन के साथ परिणामों को संसाधित करने के लिए, कोशिश करें - स्रोतों का बयान?जावा 7 स्वचालित संसाधन प्रबंधन जेडीबीसी (कोशिश-के-संसाधन विवरण)

Connection con = null; 
PreparedStatement prep = null; 

try{ 
    con = getConnection(); 
    prep = prep.prepareStatement("Update ..."); 
    ... 
    con.commit(); 
} 
catch (SQLException e){ 
    con.rollback(); 
    throw e; 
} 
finally{ 
    if (prep != null) 
     prep.close(); 
    if (con != null) 
     con.close(); 
} 
जावा 7 के साथ

आप के लिए जा सकते हैं: (Tutorial)

जावा 7 से पहले, हमेशा की तरह पैटर्न कुछ इस तरह था

try(Connection con = getConnection(); PreparedStatement prep = con.prepareConnection("Update ..."){ 

    ... 
    con.commit(); 
} 

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

क्या आप अभी भी प्रयास ब्लॉक के बाहर कनेक्शन को परिभाषित करते हैं? यहां सबसे अच्छा अभ्यास क्या है, खासकर यदि कनेक्शन पूलिंग का उपयोग किया जाता है?

+1

मैं बस उन परिस्थितियों में ऑटो-क्लोज़ का उपयोग नहीं करूंगा। जैसा कि पहले से ही कहा गया है कि यह संसाधन बंद करने के लिए है। बीटीडब्ल्यू: 'कोशिश करें ...' ब्लॉक के बाहर कनेक्शन डालने से मदद नहीं मिलेगी क्योंकि कनेक्शन को ब्लॉक करने के बाद आप रोलबैक नहीं कर सकते क्योंकि कनेक्शन पहले से बंद है। – home

+0

http://stackoverflow.com/questions/8066501/how-should-i-use-try-with-resources-with-jdbc – Raedwald

+2

@ रेडवाल्ड का संभावित डुप्लिकेट: नहीं, यह डुप्लिकेट नहीं है। यह यहाँ con.rollback() के बारे में है। – Bijan

उत्तर

37
try(Connection con = getConnection()) { 
    try (PreparedStatement prep = con.prepareConnection("Update ...")) { 
     //prep.doSomething(); 
     //... 
     //etc 
     con.commit(); 
    } catch (SQLException e) { 
     //any other actions necessary on failure 
     con.rollback(); 
     //consider a re-throw, throwing a wrapping exception, etc 
    } 
} 

oracle documentation के अनुसार, आप एक नियमित कोशिश ब्लॉक के साथ एक कोशिश के साथ-संसाधनों ब्लॉक जोड़ सकते हैं। IMO, ऊपर के उदाहरण सही तर्क है, जो दर्शाता है:

  • प्रयास PreparedStatement बंद करने के लिए कुछ भी नहीं गलत
  • कुछ भीतरी ब्लॉक में गलत हो जाता है जाता है, (कोई बात नहीं है क्या है) वापस रोल वर्तमान लेन-देन
  • प्रयास कोई फर्क नहीं पड़ता कनेक्शन बंद करने के लिए क्या
  • कुछ कनेक्शन बंद करने गलत हो जाता है, तो आप लेन-देन वापस नहीं किया जा सकता है (जैसा कि कनेक्शन है, जो अनिश्चित स्थिति में है पर एक विधि है) इसलिए, डॉन
01 को आजमाएं

जावा 6 और इससे पहले, मैं इसे कोशिश करने वाले ब्लॉक के एक छोटे से नेस्टेड सेट (बाहरी प्रयास-अंत में, मध्य प्रयास-अंत, आंतरिक प्रयास-अंत में) के साथ ऐसा करूंगा। एआरएम वाक्यविन्यास इस terser बनाता है।

+1

आपका समाधान 'SQLException' पर वापस रोल करता है, लेकिन' रनटाइम अपवाद ',' त्रुटि' (आदि) पर नहीं है, जो कि एक समस्या है। अंततः 'आधारित' कोड ऐसा करेगा। नियम "आप 'त्रुटि' नहीं पकड़ेंगे" त्रुटियों के मामले में रोलबैक को वैकल्पिक ऑपरेशन नहीं करता है। –

+0

@PiotrFindeisen: यदि आप इसे चाहते हैं, तो 'SQLException' के बजाय 'थ्रोबल' पकड़ें। आखिर में लेनदेन को रोलबैक करने के लिए सही जगह नहीं है, क्योंकि आखिरकार ब्लॉक ट्रिगर होता है कि कुछ गलत हो जाता है या नहीं। सब कुछ काम करते समय आप निश्चित रूप से रोलबैक नहीं करना चाहते हैं! –

+0

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

3

आईएमओ, इस मामले में ट्राइक-कैच के बाहर कनेक्शन और प्रीपेयरस्टेटमेंट घोषित करना सबसे अच्छा तरीका है।

1

आप लेन-देन में pooled कनेक्शन का उपयोग करना चाहते हैं, तो आप इस तरह से इसका इस्तेमाल करना चाहिए:

try (Connection conn = source.getConnection()) { 
     conn.setAutoCommit(false); 
     SQLException savedException = null; 
     try { 
      // Do things with connection in transaction here... 
      conn.commit(); 
     } catch (SQLException ex) { 
      savedException = ex; 
      conn.rollback(); 
     } finally { 
      conn.setAutoCommit(true); 
      if(savedException != null) { 
       throw savedException; 
      } 
     } 
    } catch (SQLException ex1) { 
     throw new DataManagerException(ex1); 
    } 

यह नमूना कोड autocommit मूल्य निर्धारित हैंडल।

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