2010-05-26 16 views
31

में रोलबैक के लिए एसक्लट्रांसेंस ऑब्जेक्ट तक नहीं पहुंच सकता है मुझे एक समस्या है, और मुझे मिले सभी लेख या उदाहरण इस पर ध्यान नहीं देते हैं।कैच ब्लॉक

मैं एक लेनदेन में कुछ डेटाबेस क्रियाएं करना चाहता हूं। मुझे क्या करना चाहते हैं बहुत सबसे उदाहरण के समान है:

using (SqlConnection Conn = new SqlConnection(_ConnectionString)) 
{ 
    try 
    { 
     Conn.Open(); 
     SqlTransaction Trans = Conn.BeginTransaction(); 

     using (SqlCommand Com = new SqlCommand(ComText, Conn)) 
     { 
      /* DB work */ 
     } 
    } 
    catch (Exception Ex) 
    { 
     Trans.Rollback(); 
     return -1; 
    } 
} 

लेकिन समस्या यह है कि SqlTransaction Transtry ब्लॉक के अंदर घोषित किया जाता है है। तो यह catch() ब्लॉक में पहुंच योग्य नहीं है। try ब्लॉक से पहले अधिकांश उदाहरण Conn.Open() और Conn.BeginTransaction() करते हैं, लेकिन मुझे लगता है कि यह थोड़ा जोखिम भरा है, क्योंकि दोनों कई अपवाद फेंक सकते हैं।

क्या मैं गलत हूं, या अधिकांश लोग इस जोखिम को अनदेखा करते हैं? यदि कोई अपवाद होता है तो रोलबैक करने में सक्षम होने का सबसे अच्छा समाधान क्या है?

+2

पीएस क्या आप वाकई अपवाद फेंकने के बजाय -1 (एक त्रुटि कोड) वापस करना चाहते हैं? –

उत्तर

55
using (var Conn = new SqlConnection(_ConnectionString)) 
{ 
    SqlTransaction trans = null; 
    try 
    { 
     Conn.Open(); 
     trans = Conn.BeginTransaction(); 

     using (SqlCommand Com = new SqlCommand(ComText, Conn, trans)) 
     { 
      /* DB work */ 
     } 
     trans.Commit(); 
    } 
    catch (Exception Ex) 
    { 
     if (trans != null) trans.Rollback(); 
     return -1; 
    } 
} 

या आप भी स्वच्छ और आसान जा सकते हैं और यह इस्तेमाल कर सकते हैं:

using (var Conn = new SqlConnection(_ConnectionString)) 
{ 
    try 
    { 
     Conn.Open(); 
     using (var ts = new System.Transactions.TransactionScope()) 
     { 
      using (SqlCommand Com = new SqlCommand(ComText, Conn)) 
      { 
       /* DB work */ 
      } 
      ts.Complete(); 
     } 
    } 
    catch (Exception Ex) 
    {  
     return -1; 
    } 
} 
+0

क्या दूसरा संस्करण वास्तव में रोलबैक कर रहा है जब अपवाद फेंक दिया जाता है? संपादित करें: ठीक है, प्रलेखन पढ़ने के बाद मैंने इसे देखा है। – Marks

+1

आपके पहले उदाहरण में, आपको यह निर्दिष्ट करने की आवश्यकता नहीं है कि sqlcommand लेनदेन से जुड़ा हुआ है? जैसे कि 'उपयोग (एसक्यूएल कॉमांड कॉम = नया एसक्यूएल कॉमांड (कॉमटेक्स्ट, कॉन, ** ट्रांस **)) '? या वह अनावश्यक है? क्या यह पूरी तरह से जुड़ा हुआ है? –

+0

हां, धन्यवाद। लेनदेनस्कोप के साथ, आप नहीं करते हैं, लेकिन मैं इसे अपने पहले उदाहरण से छोड़ दूंगा। तदनुसार संपादित करें। –

6

उपयोग इस

using (SqlConnection Conn = new SqlConnection(_ConnectionString)) 
{ 
    SqlTransaction Trans = null; 
    try 
    { 
     Conn.Open(); 
     Trans = Conn.BeginTransaction(); 

     using (SqlCommand Com = new SqlCommand(ComText, Conn)) 
     { 
      /* DB work */ 
     } 
    } 
    catch (Exception Ex) 
    { 
     if (Trans != null) 
      Trans.Rollback(); 
     return -1; 
    } 
} 

Btw - आप इसे सफल प्रसंस्करण के मामले में नहीं की

1

माइक्रोसॉफ्ट के नमूने, कोशिश/पकड़ see this msdn link के बाहर शुरू ट्रांस को रखें। मुझे लगता है कि BeginTransaction विधि या तो अपवाद फेंकना चाहिए या लेनदेन शुरू करना चाहिए, लेकिन दोनों कभी नहीं (हालांकि दस्तावेज यह नहीं कहता कि यह असंभव है)।

हालांकि, अगर आप TransactionScope जो आप के लिए की एक बहुत कुछ (नहीं तो) बड़े कार्य करने का प्रबंधन करता है का उपयोग करने का बेहतर हो सकता है: this link

3
using (SqlConnection Conn = new SqlConnection(_ConnectionString)) 
{ 
    try 
    { 
     Conn.Open(); 
     SqlTransaction Trans = Conn.BeginTransaction(); 

     try 
     { 
      using (SqlCommand Com = new SqlCommand(ComText, Conn)) 
      { 
       /* DB work */ 
      } 
     } 
     catch (Exception TransEx) 
     { 
      Trans.Rollback(); 
      return -1; 
     } 
    } 
    catch (Exception Ex) 
    { 
     return -1; 
    } 
} 
+0

जबकि कोड के लिए और भी कुछ है, यह निर्धारित करने में सक्षम होने के लिए यह सर्वोत्तम ग्रैन्युलरिटी प्रदान करता है कि प्रत्येक चरण क्यों विफल रहेगा। हालांकि, ध्यान दें कि एसक्यूएल कॉमांड को लेनदेन से जुड़ा होना है। – JWilliams

8

मैं प्रकार टाइपिंग और अशक्त करने के लिए चर की स्थापना पसंद नहीं है, तो :

try 
{ 
    using (var conn = new SqlConnection(/* connection string or whatever */)) 
    { 
     conn.Open(); 

     using (var trans = conn.BeginTransaction()) 
     { 
      try 
      { 
       using (var cmd = conn.CreateCommand()) 
       { 
        cmd.Transaction = trans; 
        /* setup command type, text */ 
        /* execute command */ 
       } 

       trans.Commit(); 
      } 
      catch (Exception ex) 
      { 
       trans.Rollback(); 
       /* log exception and the fact that rollback succeeded */ 
      } 
     } 
    } 
} 
catch (Exception ex) 
{ 
    /* log or whatever */ 
} 

और अगर आप MySql या किसी अन्य प्रदाता पर स्विच करना चाहता था, आप केवल 1 लाइन को संशोधित करना होगा।

0
SqlConnection conn = null; 
SqlTransaction trans = null; 

try 
{ 
    conn = new SqlConnection(_ConnectionString); 
    conn.Open(); 
    trans = conn.BeginTransaction(); 
    /* 
    * DB WORK 
    */ 
    trans.Commit(); 
} 
catch (Exception ex) 
{ 
    if (trans != null) 
    { 
     trans.Rollback(); 
    } 
    return -1; 
} 
finally 
{ 
    if (conn != null) 
    { 
     conn.Close(); 
    } 
} 
संबंधित मुद्दे