2010-07-26 10 views
6

Creo que la pregunta en sí misma es bastante autoexplicativa. El código se da a continuación -¿Por qué está comprometiendo la siguiente transacción PDO?

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

Incluso si estoy deshacer la transacción dentro del bloque catch, los datos todavía se están insertados en la base de datos. ¿Por qué?

EDITAR

Estoy añadiendo las siguientes líneas de la documentation para más aclaraciones -

Por desgracia, no todas las bases de datos soporta transacciones, por lo DOP necesita para funcionar en lo que se conoce como el modo "autocomprometir" cuando abre por primera vez la conexión . El modo de confirmación automática significa que cada consulta que ejecute tiene su propia transacción implícita, si la base de datos lo admite, o ninguna transacción si la base de datos no admite transacciones. Si necesita una transacción, debe usar el método PDO :: beginTransaction() al iniciar una. Si el controlador subyacente no es compatible con las transacciones, se lanzará una excepción PDOException (independientemente de su error al manejar las configuraciones : esta siempre es una condición de error grave). Una vez que esté en una transacción, puede usar PDO :: commit() o PDO :: rollBack() para finalizar , dependiendo del éxito del código que ejecuta durante la transacción .

Además, las siguientes líneas de la página this -

bool PDO::beginTransaction (void ) 

desactiva el modo de confirmación automática. Mientras el modo de confirmación automática está desactivado, los cambios realizados en la base de datos a través de la instancia de objeto PDO no son comprometidos hasta que finalice la transacción llamando a PDO :: commit(). Llamar a PDO :: rollBack() revertirá todos los cambios a la base de datos y devolverá la conexión al modo de confirmación automática.

Algunas bases de datos MySQL, incluyendo, de forma automática emitir una implícita COMMIT cuando un lenguaje de definición de base de datos (DDL) declaración como DROP TABLE o CREATE TABLE se emite dentro de una transacción. El COMMIT implícito impedirá que se anulen otros cambios dentro del límite de transacción.

+0

¿Qué sucede si solo retrotrae la transacción donde está lanzando actualmente una excepción? – Amber

+0

@Amber: no probé ese :( –

Respuesta

15

Debe comprobar que está utilizando INNODB como su tipo de base de datos. MyISAM no admite transacciones.

+0

El "problema" es que se supone que PDO genera una excepción si inicia una transacción con un controlador que no los admite. ¿Errores? ¿Docs malos? – cbednarski

+0

No hay pista. Todo lo que sé es que esto fue un problema para mí cuando estaba tratando de hacer transacciones usando PDO con el controlador MySQL, no se lanzaron excepciones. Podría ser un error, tendría que leer los documentos para estar seguro. EDITAR: Parece que no es un error: Devuelve TRUE en caso de éxito o FALSE en caso de error. En las páginas man para PDO-> beginTransaction –

+0

, los documentos a los que hice referencia están aquí: http://us2.php.net/manual/en/pdo.transactions .php – cbednarski

Cuestiones relacionadas