Hola a todos :
Tengo un código PHP que ejecuta 10 sentencias SQL. Me gustaría que si alguna de ellas fallase deshaga los cambios que las SQL anteriores ejecutadas.
¿es posible esto en PHP?
Gracias.
Creo que lo mejor que podrías hacer es usar los simples if/else.
En PHP lo dudo, pero si se puede en MSSQL. Crea un Store Procedure y consulta clausulas como
BEGIN TRANSACTION
ROLLBACK
@@ERROR
Por lo que he averiguado si mis tablas son MYSAM no voy a poder hacerlo.
Necesariamente las tengo que tener en MYSAM en lugar de INNODB. :(
Lo del if/else no lo entiendo, porque si las tres primeras sentencias sQL las hace correcta y la 4 fallase ¿cómo deshago las tres últimas?
Supongo que no hay forma humana de hacerlo por el tipo de mis tablas.
Gracias por los comentarios.
Pues si no funciona una sentencia SQL haces otra sentencia SQL que lo haga volver a su estado original. No es muy práctico pero debería funcionar.
MinusFour, creo que estas confundido, imagina que son 10 transacciones. Y que pasaron 9 por las clausulas IF's, en el décimo IF, hubo un error en la consulta. Como realizas un ROLLBACK de las transacciones anteriores, IMPOSIBLE o tal vez si se puede desarrollar pero sería muy tedioso!
Yo siendo tú, migraría a MSSQL.
Asi es. No puedo utilizar MSSQL porque lo tengo todo montado en MYSQL.
Gracias por los consejos.
Y que problema hay? puedes cambiar rápidamente el engine de tus tablas con: ALTER TABLE tabla ENGINE = InnoDB; y a partir de ahí ya podrás utilizar transacciones y reglas de integridad.
Según lei esto puede tener implicaciones. Haré una copia de seguridad y lo cambiaré y probaré todo.
Gracias!!
Es tedioso si son 10, yo estaba pensando en menos queries xD.
function do_mysql_queries(){
if(mysql_query($sql1) == false){ return 1;}
if(mysql_query($sql2) == false){ return 2;}
if(mysql_query($sql3) == false){ return 3;}
if(mysql_query($sql4) == false){ return 4;}
return 0;
}
function undo_mysql_queries($err_num){
switch($err_num){
case 4: mysql_query($undoQuery3);
case 3: mysql_query($undoQuery2);
case 2: mysql_query($undoQuery1);
case 1: return false;
default: return true;
}
}
if(undo_mysql_queries(do_mysql_queries())){
echo "Se ejecutaron las consultas satisfactoriamente. ";
} else {
echo "Hubo un fallo en las consultas";
}
También encontre esto, pero dice que es para php 4 así que no se que tanto te sirva.
http://www.deepbluesky.com/blog/-/myisam-transactions_20/
Cita de: MinusFour en 14 Julio 2010, 13:58 PM
También encontre esto, pero dice que es para php 4 así que no se que tanto te sirva.
http://www.deepbluesky.com/blog/-/myisam-transactions_20/
mmm...realmente interesante!!. Tomo nota!!
muchas gracias!! :)
No entendí muy bien lo que hizo MinusFour. Es decir,
.. en la función do_mysql_queries, en la variable $sql(1|2|3|4) se ponen las querys que se van a ejecutar.
.. en la función undo_mysql_queries, en la variable $undoQuery(1|2|3|4), las querys para devolver los cambios efectuados?
No lo veo muy cómodo que digamos.
Yo tampoco lo veo cómodo porque deshacer un INSERT es costoso.
Simón, o tal vez se podría realizar, pero generando tablas temporales. Si pasan por todos los IF's sin errores, se volcan en las tablas originales. De lo contrario se eliminaría el contenido de la tabla temporal.
¿¿Tampoco lo termino de ver porque si haces tablas temporales que pasaría cuando dos personas acceden simultáneamente??
no pasaría nada, ya que para eso debes de tener un ID! para la identificación de los datos por cada usuario. Pero obviamente sería tedioso. Sigo con el mismo concejo que te di.
Yo en cambio pienso que la alternativa de minusfour puede ser buena si realmente funciona. (Todavía no la he probado).
http://www.deepbluesky.com/blog/-/myisam-transactions_20/
innodb se creó precisamente para esto, cualquier apaño que metas mediante código no será ni la mitad de fiable y eficiente.
Además no veo que problema puede darte el cambio, algunas consultas puede que sean ligeramente más lentas para tablas del orden del millón de registros pero en esos casos hay otras soluciones que no implican usar un engine antiguo.
En fin, suerte.