Blog de Gonzalo

TRANSACCIONES CON VARIAS QUERIES

Una transacción es un conjunto de operaciones sql que se ejecutan como un único bloque, es decir, si falla una operación fallan todas. Es una unidad única de trabajo. Si una transacción tiene éxito, todas las modificaciones de los datos realizadas durante la transacción se confirman y se convierten en una parte permanente de la base de datos. Si una transacción encuentra errores y debe cancelarse o revertirse, se borran todas las modificaciones de los datos.
Usar transacciones es muy simple: antes de ejecutar la primer consulta, se ejecuta una que solamente contiene BEGIN. Luego se ejecutan las consultas que deban ejecutarse. Si el resultado de las consultas resultan exitosas, se termina la transacción con COMMIT, lo cual provoca que los cambios hechos por las consultas anteriores sean permanentes. Si las consultas fallan en algún paso, se puede volver al estado anterior al comienzo de la transacción ejecutando ROLLBACK.
Aunque los datos no sean realmente escritos a la o las tablas involucradas hasta ejecutar el COMMIT, las consultas devuelven lo mismo que si lo fueran, es decir, para saber si una consulta falló basta con ver el valor de retorno de mysql_query y para ver el número de filas afectadas sigue valiendo usar mysql_num_rows.
Mientras la transacción está ejecutándose, los datos (en el caso de InnoDB las filas y en el caso de MyISAM las tablas) afectados quedan bloqueados, nadie puede acceder a ellos. Cualquier consulta que tenga que ver con los mismos datos será demorada hasta que la transacción termine. Esto implica que usar transacciones es un poco más lento que no usarlas, pero a la vez implica que los datos involucrados no pueden ser modificados por otra copia de la aplicación, y por lo tanto se evita la situación planteada al principio como ejemplo.
Os pongo un ejemplo para que se vea lo sencillo que es:


$dbh = mysql_connect($host,$user,$pass);
mysql_select_db($base_de_datos,$dbh);
//Empieza la transacción
$sql = "SET AUTOCOMMIT=0;";
$resultado = mysql_query($sql, $dbh);
$sql = "BEGIN;";
//Consultas dentro de la transacción como inserts o updates.
....
//ultima query
$result = mysql_query($sql, $dbh);
if ($resultado)
{
//Si todo ha ido bien se hace commit y se guardan los datos
$sql = "COMMIT";
$resultado = mysql_query($sql, $dbh);
}
else
{
//Si ha ido mal se hace rollback y se guardan los datos
$sql = "ROLLBACK;";
$resultado = mysql_query($sql, $dbh);
}

Compartir en twitter