2009-07-05 18 views
12

Utilizo el siguiente código para transacciones en Zend Framework pero la función de reversión no funciona (los datos se insertan en la base de datos mediante insertSome ($ data)). ¿Qué pasa?No se puede deshacer la transacción en Zend Framework

  $db->beginTransaction(); 
      try{ 
       $model->insertSome($data); 
       $model->insertAll($data2); //this line cannot be run and the whole transaction should be rolled back. 
       $db->commit(); 
      } catch (Exception $e) { 
       $db->rollBack(); 
       echo $e->getMessage(); 
      } 
+7

¿Su DB es por casualidad MySQL usando tablas MyISAM? No admiten transacciones. Tendría que usar tablas InnoDB si desea soporte de transacciones. – nos

+0

Sí, estoy usando tablas MyISAM. He cambiado a tablas InnoDB y funciona. Gracias. – Billy

Respuesta

20

no podemos llegar a esta pregunta fuera de la lista de preguntas sin respuesta "" en la stackoverflow a menos que haya al menos una respuesta con un upvote. Así que estoy repitiendo la solución que discutiste arriba en los comentarios.

@nos sugiere:

Está su base de datos, por casualidad, MySQL utilizando tablas MyISAM? No son compatibles con las transacciones . Tendría que usar las tablas InnoDB si desea la transacción .

responde @Billy:

Sí, estoy usando tablas MyISAM. He cambiado a tablas InnoDB y funciona. Gracias.

(He marcado esto como una respuesta wiki de la comunidad por lo que no reciben puntos de ella.)

2

Si mi mesa era InnoDB, (visto de SHOW CREATE TABLE xxx) y mi transacción no retrocedía, ¿qué sugieres?

CREATE TABLE `EarningCode` (
`ID` int(11) NOT NULL auto_increment, 
`EarningCode` varchar(16) collate utf8_unicode_ci NOT NULL, 
`Description` varchar(255) collate utf8_unicode_ci NOT NULL, 
`DateEffective` timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP, 
`Rate` float NOT NULL, 
PRIMARY KEY (`ID`) 
) ENGINE=InnoDB AUTO_INCREMENT=1239 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci 

Es parte de las pruebas unitarias: Tengo un método establecido que inicia una transation:

protected function setUp() 
{ 
    global $db; 

    $db->beginTransaction(); 

    // Insert this tested object into db. 
} 

y un método de desmontaje que debe asegurarse de que la fila no se inserta en la base de datos (cada uno una vez que se ejecuta una prueba en esta clase de prueba, ejecuta el par setUp/tearDown y, por lo tanto, no quiero duplicados que llenen mi tabla db).

protected function tearDown() 
{ 
    global $db; 

    $db->rollBack(); 
} 

He comprobado lo que SQL se ejecuta, y puedo ver que el compromiso automático se establece en false cuando se inicia la transacción, y cambió a cierto después de retroceder, pero permanece inserta la fila.

0

Tu código es correcto.

Marque la opción de su tabla. Necesita usar el motor Transacctional con InnoDb

2

Para uso futuro, para saber si realmente es una excepción de base de datos, utilice Zend_Db_Exception en su lugar.

} catch (Zend_Db_Exception $e) { 
    $db->rollBack(); 
    echo $e->getMessage(); 
} catch (Exception $e) { 
    echo $e->getMessage(); 
}