2010-03-11 35 views
8

我正在通過this tutorial關於PDO,並已談到交易。跳過連接部分,我有這樣的PHP代碼:PDO:交易不回滾?

try 
{ 
    $db->beginTransaction(); 

    $db->exec('DROP TABLE IF EXISTS animals'); 

    $db->exec('CREATE TABLE animals (' 
     .'animal_id MEDIUMINT(8) NOT NULL AUTO_INCREMENT PRIMARY KEY,' 
     .'animal_type VARCHAR(25) NOT NULL,' 
     .'animal_name VARCHAR(25) NOT NULL)' 
     .'ENGINE=INNODB'); 

    $db->exec('INSERT INTO animals (animal_type, animal_name) VALUES ("emu", "bruce")'); 
    $db->exec('INSERT INTO animals (animal_type, animal_name) VALUES ("funnel web", "bruce")'); 
    $db->exec('INSERT INTO animals (animal_type, animal_name) VALUES ("lizard", "bruce")'); 
    $db->exec('INSERT INTO animals (animal_type, animal_name) VALUES ("dingo", "bruce")'); 
    $db->exec('INSERT INTO animals (animal_type, animal_name) VALUES ("kangaroo", "bruce")'); 
    $db->exec('INSERT INTO animals (animal_type, animal_name) VALUES ("wallaby", "bruce")'); 
    $db->exec('INSERT INTO animals (animal_type, animal_name) VALUES ("wombat", "bruce")'); 
    $db->exec('INSERT INTO animals (animal_type, animal_name) VALUES ("koala", "bruce")'); 
    $db->exec('INSERT INTO animals (animal_type, animal_name) VALUES ("kiwi", "bruce")'); 

    $db->commit(); 

    echo 'Table re-created and data entered successfully.'; 
} 
catch(PDOException $e) 
{ 
    $db->rollback(); 

    echo $e->getMessage(); 
} 

它運行偉大的,像我想的那樣,除非我把一個錯誤的地方。就像我在第四個插入語句中創建了一個錯誤,我會在數據庫中找到三個動物。但我認爲事情應該被回滾,這意味着我會在運行這個腳本之前找到數據庫。

我誤解了一些東西嗎?我錯過了什麼?事務和回滾函數是否做了我認爲他們應該做的事情?是否下降並創建聲明以某種方式「打破」交易?這裏發生了什麼?


更新:如果我移動$db->beginTransaction();線,因此已創建表後,纔開始交易,我得到我所期待的行爲。因此,如果第三條插入語句失敗,那麼在事務回滾之後,我會有一個空表(因爲它剛剛重新創建)。仍然不知道爲什麼它不工作時下降,並創建語句是,雖然交易...

回答

18

檢查PHP參考手冊:PDO::beginTransaction

有些數據庫,包括MySQL,自動發出一個隱含COMMIT時數據庫定義語言(DDL)語句(如DROP TABLE或CREATE TABLE)在事務內發佈。隱式COMMIT將阻止您回滾事務邊界內的任何其他更改。

這解釋了爲什麼會發生這種情況,這是MySQL的限制,而不是PDO/PHP的限制。

+0

Ahaaa。這就說得通了!謝謝:) – Svish

2

確保所有表都支持事務。例如MyISAM不支持,例如 。

+2

這是一個評論比答案更多。 – hakre