2010-03-11 10 views
8

Estoy pasando por this tutorial sobre PDO y he llegado al punto sobre las transacciones. Saltarse las piezas de conexión, tengo este código php:PDO: las transacciones no retroceden?

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(); 
} 

Se ejecuta muy bien y como pensé que lo haría, excepto si pongo en un error en alguna parte. Como si hubiera creado un error en la cuarta declaración de inserción, encontraría tres animales en mi base de datos. Pero pensé que se suponía que las cosas iban a retroceder, lo que significa que encontraría la base de datos como estaba antes de ejecutar este script.

¿He entendido mal algo? ¿Qué me estoy perdiendo? ¿Las funciones de transacción y retrotracción hacen algo más de lo que creo que deberían estar haciendo? ¿Las suspensiones y las declaraciones de creación "rompen" la transacción de alguna manera? ¿Que está pasando aqui?


Actualización: Si muevo la línea $db->beginTransaction(); por lo que la transacción comienza sólo después de que la tabla se ha creado, consigo el comportamiento que yo esperaba. Entonces, si el tercer enunciado de inserción falla, tendré una tabla vacía (ya que recién fue recreado) después de que la transacción se haya retrotraído. ¿Todavía te preguntas por qué no funciona cuando la caída y crear declaraciones están en la transacción, aunque ...

Respuesta

18

compruebe el manual de referencia de PHP: PDO::beginTransaction

Algunas bases de datos, incluyendo MySQL, emitirá automáticamente un COMMIT implícito cuando una sentencia de lenguaje de definición de base de datos (DDL) como DROP TABLE o CREATE TABLE se emite dentro de una transacción. El COMMIT implícito le impedirá deshacer cualquier otro cambio dentro del límite de la transacción.

Esto explica por qué sucede esto, y es una limitación de MySQL, no de PDO/PHP.

+0

Ahaaa. ¡Eso tiene sentido! Gracias :) – Svish

2

asegúrese de que todas las tablas admitan transacciones. por ejemplo MyISAM no es compatible.

+2

que es más un comentario que una respuesta. – hakre

Cuestiones relacionadas