2010-09-01 11 views
6

मेरे पास दो जटिल PHP ऑब्जेक्ट्स हैं, जिनमें से प्रत्येक में कुछ MySQL तालिकाओं में डेटा है।PHP पीडीओ ऑब्जेक्ट कैसे पता लगा सकता है कि यह पहले से ही एक MySQL लेनदेन में है?

कभी कभी, मैं सिर्फ डेटाबेस से एक वस्तु एक को हटाने की जरूरत है, और है कि 3 SQL कथन लेता है।

कभी कभी, मैं डेटाबेस है, जो 4 SQL कथन लेता है से एक वस्तु बी को दूर करने की जरूरत है, और भी खोजने के लिए और वस्तु एक की उस वस्तु बी के स्वामित्व की सभी को दूर करने की जरूरत है जो।

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

मैं delete_A की परिभाषा() को कैसे अपडेट कर अगर वहाँ पहले से ही एक बड़ा चल लेन-देन नहीं है केवल एक नई लेन-देन को खोलने के लिए।

मैं कुछ इस तरह करने में सक्षम होने की उम्मीद है, लेकिन अपने स्वयं के PDOConnect वर्ग है, जो एक $hasTransaction चर है बनाने के लिए है autocommit विशेषता के आधार पर beginTransaction()

function delete_A($a){ 
    global $pdo; 
    $already_in_transaction = !$pdo->getAttribute(PDO::ATTR_AUTOCOMMIT); 
    if(!$already_in_transaction){ 
    $pdo->beginTransaction(); 
    } 

    //Delete the A 

    if(!$already_in_transaction){ 
    $pdo->commit(); 
    } 
} 
function delete_B($b){ 
    global $pdo; 
    $pdo->beginTransaction(); 
    foreach($list_of_As as $a){ 
    delete_A($a); 
    } 
    $pdo->commit(); 
} 
+0

आप विदेशी कुंजी बाधाओं का उपयोग करने पर विचार करना चाहेंगे (मतलब है कि आपको myISAM से उन इंजनों में स्विच करना होगा जो उन्हें समर्थन देते हैं) - इस तरह आप डीबी को आपके लिए अनुकरण करने के बजाय आपके लिए डिस्लेड कर सकते हैं। – prodigitalson

उत्तर

2

मैं सिर्फ अपवाद ->beginTransaction() द्वारा फेंका का उपयोग कर बाहर है कि क्या मैं एक सौदे में था लगाने की है, और का उपयोग कर कि क्या तय करने के लिए समाप्त हो गया आंतरिक पाश में प्रतिबद्ध करने के लिए।संशोधन के बिना

function delete_A($a){ 
    global $pdo; 
    try { 
    $pdo->beginTransaction(); 
    } catch (PDOException $e) { 
    $already_in_transaction = true; 
    } 

    //Delete the A 

    if(!$already_in_transaction){ 
    $pdo->commit(); 
    } 
} 

और delete_B() काम करता है: तो delete_A() की तरह लग रही समाप्त हो गया।

+0

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

1

एक तरह से बदल दिया है करने के लिए प्रकट नहीं होता है । फिर आप बस इसे जांचें। Php.net पर startTransaction फ़ंक्शन की टिप्पणियों पर एक उदाहरण पाया जा सकता है http://www.php.net/manual/en/pdo.begintransaction.php#81022

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

साइड नोट याद रखें कि आपकी तालिका कार्य करने के लिए लेनदेन के लिए INNODB होना चाहिए। और चूंकि आपको काम करने के लिए लेनदेन के लिए INNODB में होना आवश्यक है, इसलिए आपको प्रोडिगिटल्सन की सलाह लेनी चाहिए और विदेशी कुंजी बाधाओं का उपयोग करना चाहिए।

7

PDO::ATTR_AUTOCOMMIT, एक संकेतक विशेषता नहीं है, यह एक नियंत्रण विशेषता है। यह नियंत्रित करता है कि एसक्यूएल कथन पूर्ण होने पर पूर्ण रूप से प्रतिबद्ध होते हैं या नहीं।

अगर आप किसी लेन-देन बकाया प्रतिबद्ध या वापस लुढ़का होने की जरूरत है कि आप PDO::inTransaction() जो 0 रिटर्न अगर आप प्रगति में कोई लेन-देन है, और 1 कॉल कर सकते हैं। हालांकि, यह फ़ंक्शन दस्तावेज नहीं है, इसलिए यह कहना मुश्किल है कि पीडीओ के सभी भावी संस्करणों में मौजूद होने पर निर्भर होना सुरक्षित है या नहीं।

मैं अनुशंसा करता हूं कि PHP डेवलपर्स फ़ंक्शन या क्लास स्कोप के भीतर लेनदेन प्रबंधित करने का प्रयास न करें। आपको आवेदन के शीर्ष-स्तर पर लेन-देन प्रबंधित करना चाहिए।

यह भी देखें:

+0

लिंक के लिए धन्यवाद, जिसने मुझे समाधान का उपयोग करने के लिए प्रेरित किया। –

+2

inTransaction() अब दस्तावेज किया गया है। http://php.net/manual/en/pdo.intransaction.php – morbidCode

+0

@morbidCode, अद्यतन के लिए धन्यवाद! –

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