February 12th, 2010 Category: base de datos mysql Programacion Zend Framework
5 Comments »
Una transacción es un conjunto de operaciones en la base que se
ejecutan por separadas pero están relacionadas la una con la otra y
necesitamos que si se ejecuta una operación se asegure que también lo
haga en las operaciones siguientes.
En los tipos de tablas transaccionales (InnoDb y DBD ) de MySql,
tenemos la opción de determinar cuando hacer un commit, esto nos
permite hacer un rollback en el caso de que no estemos felices con el
resultado de nuestra transacción.
En las tablas del tipo no transaccional (MyIsam) esta opción no
existen porque están seteadas para que se haga un auto commit, esto
significa que no vamos a poder usar transacciones para tablas de Tipo
MyIsam, solo para InnoDb.
Con las tablas InnoDb nosotros podemos controlar cuando hacer el
commit. Podemos revisar que todas las operaciones se hayan realizado
de forma correcta y recién ahí hacer un commit de la transacción.
Con esta forma nosotros nos aseguramos que una operación se ejecute en
su totalidad, e informar al usuario o a quien sea necesario el
resultado de la misma.
La gente de Doctrine en su blog comentan que su ORM aumenta la
velocidad de mysql, ya que ellos manejan transacciones de forma nativa
en todas sus operaciones,
http://www.doctrine-project.org/blog/transactions-and-performance .
Les recomiendo que lean el articulo, aunque esta en ingles es bastante
claro. Quizás el articulo los entusiasme y se metan un poco en el
mundo de los ORM.
Zend Framework como no podía de ser de otra forma tiene soporte para
transacciones. Si tenemos ZF en un sistema con MVC, y tenemos que
hacer una transacción que involucre mas de un modelo, la transacción
la podemos abrir en cualquiera de ellos, y comitearla.
La forma correcta es conseguir el adapter. El cual nos brinda la
interfaz con la conexion a la base de datos. El mismo lo podemos
conseguir llamando al metodo getAdapter de cualquiera de nuestros
modelos.
class TestController extends Zend_Controller_Action
{
public function createAction()
{
$params = $this->_getAllParams();
$model1 = new MyFirstModel();
$model2 = new MySecondModel();
//Conseguimos el Adapter de nuestra conexion
$db = $model1->getAdapter();
// Iniciamos la transaccion
$db->beginTransacction();
try{
$model1->insert( $params );
$model1->insert( $params );
// Sino hubo ningun inconveniente hacemos un commit
$db->commit();
} catch( Exception $e ) {
// Si hubo problemas. Enviamos todo marcha atras
$db->rollBack;
}
}
}
En el código de ejemplo podemos ver como recibimos ciertos datos por
POST/GET y los datos los guardamos en dos modelos diferentes, esas
acciones están dentro de un try/catch, el que nos permite atrapar las
excepciones que podrían ser enviada por alguna de las operaciones que
tenemos dentro de la transacción en cuyo caso ejecutamos el rollback.
Si todo salio bien llamamos al metodo commit.
Si nosotros queremos forzar dentro de nuestros modelos un rollback lo
mas transparente es tirar una excepcion, y desde el controller se
ejecuta el rollback. La forma de generar una excepcion es la
siguiente.
Para saber mas de transacciones nada mejor que ir a las fuentes originals.
MySql http://dev.mysql.com/doc/refman/5.0/es/ansi-diff-transactions.html
Zend Framework http://framework.zend.com/manual/1.10/en/zend.db.adapter.html#zend.db.adapter.transactions


