2010-07-26 16 views
6

मुझे लगता है कि सवाल स्वयं ही आत्म-व्याख्यात्मक है। कोड नीचे दिया गया है -निम्नलिखित पीडीओ लेनदेन क्यों कर रहा है?

<?php 
    $PDO = NULL; 
    $pdo_dsn = 'mysql:host=localhost;dbname=pdo_test'; 
    $pdo_persistence = array(PDO::ATTR_PERSISTENT => true); 
    $db_user = 'root'; 
    $db_pass = ''; 
    $db_query = "INSERT INTO person(name, address) 
        VALUES ('Mamsi Mamsi', 'Katabon')"; 

    try 
    { 
      $PDO = new PDO($pdo_dsn, $db_user, $db_pass, 
           $pdo_persistence); 
    } 
    catch(PDOException $e) 
    { 
      echo "Error occured: ". $e->getMessage(); 
      die(); 
    } 

    $PDO->setAttribute(PDO::ATTR_ERRMODE, 
          PDO::ERRMODE_EXCEPTION); 
    $PDO->setAttribute(PDO::ATTR_AUTOCOMMIT, false); 

    try 
    { 
      $PDO->beginTransaction(); 
      $PDO->exec($db_query); 

      throw new PDOException('Generated Exception'); 

      $PDO->commit(); 
    } 
    catch(PDOException $e) 
    { 
      echo "An error occured while doing a database transaction. The 
      error message is : ".$e->getMessage(); 

      $PDO->rollBack(); 
      die(); 
    } 
?> 

यहां तक ​​कि अगर मैं कैच ब्लॉक के अंदर लेन-देन वापस रोलिंग हूँ, डेटा अभी भी डेटाबेस में डाला जा रहा है। क्यूं कर?

संपादित

मैं आगे स्पष्टीकरण के लिए documentation से कुछ पंक्तियां निम्नलिखित द्वारा जोड़ा जा रहा -

दुर्भाग्य से, नहीं हर डेटाबेस इसलिए पीडीओ की जरूरत है के रूप में जाना जाता है में चलाने के लिए लेन-देन का समर्थन करता है, जब आप पहली बार कनेक्शन खोलते हैं तो "ऑटो-प्रतिबद्ध" मोड। ऑटो-प्रतिबद्ध मोड का अर्थ है कि आपके द्वारा चलाए जाने वाले प्रत्येक प्रश्न में डेटाबेस का समर्थन करता है, या डेटाबेस लेनदेन यदि डेटाबेस लेन-देन का समर्थन नहीं करता है तो इसका अपना अंतर्निहित लेनदेन है। यदि आपको एक लेनदेन की आवश्यकता है, तो आपको पीडीओ :: startTransaction() विधि का उपयोग पर शुरू करना होगा। यदि अंतर्निहित चालक लेनदेन का समर्थन नहीं करता है, एक पीडीओएक्सप्शन फेंक दिया जाएगा (चाहे आपकी त्रुटि सेटिंग्स को संभालने के बावजूद: यह हमेशा एक गंभीर त्रुटि स्थिति है)। एक बार जब आप लेनदेन में हों, तो आप लेनदेन के दौरान चलाए गए कोड की सफलता के आधार पर को समाप्त करने के लिए पीडीओ :: प्रतिबद्ध() या पीडीओ :: रोलबैक() का उपयोग कर सकते हैं।

इसके अलावा, this पेज से निम्नलिखित लाइनों -

bool PDO::beginTransaction (void ) 

autocommit मोड बंद कर देता है। जबकि autocommit मोड बंद है, पीडीओ ऑब्जेक्ट इंस्टेंस के माध्यम से डेटाबेस में किए गए परिवर्तन तब तक प्रतिबद्ध नहीं हैं जब तक आप पीडीओ :: प्रतिबद्ध() को कॉल करके लेनदेन समाप्त नहीं करते। कॉलिंग पीडीओ :: रोलबैक() डेटाबेस में सभी परिवर्तन वापस रोल करेगा और कनेक्शन को ऑटोोकॉमिट मोड में वापस कर देगा।

MySQL सहित कुछ डेटाबेस,, स्वचालित रूप से मुद्दा निहित COMMIT जब एक डेटाबेस परिभाषा भाषा (DDL) बयान जैसे ड्रॉप टेबल या CREATE TABLE एक सौदे के भीतर जारी किया जाता है। निहित COMMIT आपको लेनदेन सीमा के भीतर किसी अन्य परिवर्तन को वापस लाने से रोक देगा।

+0

क्या होता है यदि आप केवल लेनदेन को रोलबैक करते हैं जहां आप वर्तमान में अपवाद फेंक रहे हैं? – Amber

+0

@Amber: उस परीक्षण का परीक्षण नहीं किया :( –

उत्तर

15

आपको यह जांचना चाहिए कि आप अपने डेटाबेस प्रकार के रूप में INNODB का उपयोग कर रहे हैं। MyISAM लेनदेन का समर्थन नहीं करता है।

+0

"समस्या" यह है कि पीडीओ को अपवाद उठाना है यदि आप एक ड्राइवर का उपयोग करके लेनदेन शुरू करते हैं जो उनका समर्थन नहीं करता है। बग? खराब दस्तावेज़? – cbednarski

+0

कोई सुराग नहीं है। मुझे पता है कि यह मेरे लिए एक मुद्दा था जब मैं पीडीओ का उपयोग MySQL चालक के साथ लेनदेन करने की कोशिश कर रहा था, कोई अपवाद कभी नहीं फेंक दिया गया था। एक बग हो सकता है, मुझे यह सुनिश्चित करने के लिए दस्तावेज़ों को पढ़ना होगा। संपादित करें: ऐसा प्रतीत होता है कि यह एक बग नहीं है: विफलता पर सफलता या गलत पर सत्य लौटाता है। पीडीओ के लिए मैन पेज से-> startTransaction –

+0

डॉक्स I संदर्भित यहां हैं: http://us2.php.net/manual/en/pdo.transactions .php – cbednarski

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