Ver Mensaje Individual
  #6 (permalink)  
Antiguo 20/05/2010, 04:57
quimfv
Colaborador
 
Fecha de Ingreso: marzo-2008
Ubicación: Sabadell
Mensajes: 4.897
Antigüedad: 16 años, 1 mes
Puntos: 574
Respuesta: RollBack de varios Insert

No ... el ROLLBACK lo tienes que hacer al final de todo el proceso...

//Inicializo el objeto
objConn=new Conn(.....)
//Inicializo la variable de control
error=0;
//Inicializo la transacció
objConn-> instrucción_segura ("BEGIN");
//Hago n operaciones con la bbdd
INSERTs UPDATEs, DELETEs
//Modifico la variable error en funcion del resultado de las operaciones

//Si NO hay error
//Hago otras operaciónes (p.e. mando un mail)
//Tambien registro el posible error en la misma variable


//Cierro la transacción
//Si hay error lanzo el ROLLBACK (este deshara TODAS las operaciones hechas a la bbdd desde el BEGIN)
//Si NO hay error lanzo el COMMIT


Obviamente puedes abortar el proceso con algun break o GO TO si al encontrar el primer error ya invalida todo el proceso...

En realidad como el control del error lo hacemos con una variable externa podemos controlar qualquier error no solo los de bbdd ... así es como si el envio del mail fuera una operación mas dentro de la transacción y por tanto lanzare el ROLLBACK si falla... como si hubiese fallado una operacion de la BBDD.

El ROLLBACK es para deshacer aquello que se ha hecho no lo que no se ha hecho, luego en tu codigo hay algo que no tiene sentido

PRIMERA OPERACION CON LA BBDD
$resultado_insert1 = $Data->qryNoRes($INSERT1);
if (!$resultado_insert1) $Data-> instrucción_segura ("ROLLBACK");
Si FALLA hago ROLLBACK

esto no tiene sentido puesto que si ha fallado no hay nada que deshacer (ROLLBACK--> rodar para atras ->retroceder), en todo caso si la primera operacion te falla lo que tienes que evitar es que se hagan las demas, especialmente el envio del mail, puesto que si este se realiza no habra ROLLBACK posible para retrocederlo... (Si tendria sentido des de el punto de vista de cerrar la transacción)

No se si me he explicado, el sentido del tratamento de transacciones es el de poder "deshacer" aquello que se haya hecho no lo que no se ha hecho!!!

Si despues de una serie de operaciones hechas se produce algo que las hace invalidas deshacerlas TODAS para dejar la BBDD en el estado anterior...


Quim

Edito: Como no estoy seguro de saber explicarme te lo doy hecho
Código PHP:
Ver original
  1. <?php
  2. /*
  3. *Supongamos que
  4. *qryNoRes() retorna true si no hay error
  5. *                   false se se produce un error
  6. * Send()    retorna true si no hay error
  7. *                   false se se produce un error
  8. */
  9.  
  10. $Data = new CBaseDatos(st_host,st_user,st_pass,st_db);
  11. $Data-> instruccion_segura ("BEGIN");
  12. $error=false;
  13.  
  14. if ($Data->qryNoRes($INSERT1)){
  15.     if ($Data->qryNoRes($INSERT2)){
  16.         // Si los dos se ejecutan correctamente
  17.         if ($Mail->Send()){
  18.             $Data->instruccion_segura ("COMMIT");
  19.             echo "Todo correcto";
  20.         }else{
  21.             //Si hay error en el mail
  22.             $error=true;
  23.         }
  24.     }else{
  25.         //Si hay error en el segundo INSERT
  26.         $error=true;
  27.     }
  28. }else{
  29.         //Si hay error en el primer INSERT
  30.         $error=true;
  31. }
  32.  
  33. if($error) $Data-> instruccion_segura ("ROLLBACK");
  34. ?>

Última edición por quimfv; 20/05/2010 a las 05:18