2010-04-09 9 views
6

मैं एक डेटाबेस तालिका है कि लग रहा हैरखना एक नाशक पर कि क्या कोई अपवाद घटित आधार पर भिन्न कार्यवाही ले

तरह
try 
{ 
    db.execute("BEGIN"); 
    // Lots of DELETE and INSERT  
    db.execute("COMMIT"); 
} 
catch (DBException&) 
{ 
    db.execute("ROLLBACK"); 
} 

मैं एक आरए II वर्ग तो मैं कर सकता में लेन-देन तर्क लपेट करना चाहते हैं अद्यतन करने के लिए कुछ कोड है बस

{ 
    DBTransaction trans(db); 
    // Lots of DELETE and INSERT 
} 

लिखने लेकिन कैसे मैं इसके लिए नाशक लिखना चाहते हैं?

उत्तर

12

निम्नलिखित का प्रयोग है:

transaction tr(db); 
... 
tr.commit(); 

tr.commit() पूरा करने के बाद यह राज्य सेट "हो गया प्रतिबद्ध" करने के लिए और विनाशक कुछ भी नहीं करता, अन्यथा यह रोलबैक करता है।

अपवाद के लिए जांच की जा रही बुरा विचार है, पर विचार करें:

transaction tr(db); 
... 
if(something_wrong) 
    return; // Not throw 
... 
tr.commit(); 

इस मामले में आप शायद उम्मीद नहीं बल्कि रोलबैक तब प्रतिबद्ध लेकिन प्रतिबद्ध किए जाएंगे।

संपादित करें: लेकिन अगर आप अभी भी यह बुरी तरह से करना चाहते हैं, std::uncaught_exception() पर एक बार देख ले, लेकिन यह पहली http://www.gotw.ca/gotw/047.htm

+1

+1 इस तरह की चीजें कैसे की जाती हैं। यद्यपि एक समस्या है: क्या होगा यदि आप प्रतिबद्ध() को कॉल करना भूल जाते हैं? – sharptooth

+2

और यदि आप लेनदेन चर बनाने के लिए भूल जाते हैं? आप सभी गलतियों को रोक नहीं सकते हैं। –

+2

@ शार्पतोथ: क्या होगा यदि आप उन बदलावों को भूल गए जो आप पहले स्थान पर करना चाहते थे? मुझे नहीं लगता कि आप अक्षमता के खिलाफ सुरक्षा के लिए बहुत कुछ कर सकते हैं। – jalf

1

सबसे आसान तरीका मैं सोच सकता हूं कि अपवाद में कक्षा में एक निजी सदस्य चर सेट करना होगा, और इसे विनाशक में उचित कार्रवाई/परीक्षण करना होगा।

3

आप उपयोग कर सकते हैं निम्नलिखित तर्क:

  1. एक commit_done बूलियन मान अपने लेन-देन वर्ग के लिए झूठी को प्रारंभ करें।
  2. आपके कन्स्ट्रक्टर में, लेनदेन शुरू करें।
  3. लेनदेन को "प्रतिबद्ध" करने के लिए एक विधि जोड़ें और commit_डोन अपडेट करें।
  4. अपने नाशक में, कहते हैं "रोलबैक" केवल तभी commit_done अभी भी झूठी
2

पढ़ अपवाद संचालन को हटाने के लिए, आप अपने आरए II गंभीर हो रहे हैं।

कोड होना चाहिए

try 
{ 
    DBTransaction trans(db) ; 

    // Lots of DELETE and INSERT 
    // should one fail, a DBTransactionRollback exception will be thrown 

    trans.commit() ; 
} 
catch(const DBTransactionRollback & e) 
{ 
    // If really needed, you could extract failure information from "e" 
} 

अपने मूल कोड के साथ मतभेद क्या मेरा उत्तर प्रेरित होते हैं:

  1. "पकड़" की जरूरत कुछ भी नहीं है: नाशक एक स्वचालित समझेंगे रोलबैक जब तक प्रतिबद्ध() विधि सफलता () के साथ बुलाया गया था, उदाहरण के लिए, डीबीट्रांसक्शन के कुछ निजी बूलियन सदस्य को पर सेट कर सकते हैं)। पकड़ वह है जहां लेनदेन जारी रहेगा, लेनदेन असफल रहा।

  2. आप एक समर्पित अपवाद बनाना चाहिए (मैं इसे DBTransactionRollback नाम) फेंक पल कुछ अपने आदेशों में से एक में विफल रहता है। इस प्रकार, पकड़ केवल लेन-देन रोलबैक से प्रेरित अपवाद (एसटीएल की तरह, आदि) आप एक से अधिक कार्यों में अपने कोड, से इस कोशिश/कहा जाता है डाल करने के लिए सक्षम पकड़ेगा और नहीं अन्य अपवाद

  3. अपवाद तंत्र के उपयोग बुलियन रिटर्न और अन्य त्रुटि कोड रिटर्न से निपटने के बिना, कोड का ब्लॉक ब्लॉक करें।

आशा है कि यह आपके प्रश्न का उत्तर देगा।

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

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