Flujo De Transaciones

Buenas a to2,

Estoy utilizando transacciones en mis aplicaciones y no estoy seguro del flujo que realizan,

Pondre un ejemplo:




$transaction=Yii::app()->db->beginTransaction();

$errorSave=0;					

for($j=0;$j<=$z;$j++)

...

  if($model->save()){

    $errorSave=0;

  }else{

    errorSave=1;

    $transaction->rollBack();

  }

}


if($errorSave==0){					

 $transaction->commit();

}



Inicializo la transaccion,inicializo la variable errorSave a 0, entra al bucle y va insertando, si en algún momento falla al guardar el modelo, realiza un rollback, que entiendo que es que vuelve a intentarlo(pero nose cuantas veces…), en el caso de haber fallado, pongo la variable errorSave a 1, , si lo consigue guardar o no el modelo no lo se, dado que a la siguiente vuelta si no falla la variable errorSave se pone de nuevo a 0 y hara el commit…

Cual es la lógica/flujo correcta con las transacciones?

Gracias.

Creo que el error está en la concepción de las transacciones.

En realidad funciona así:

START TRANSACTION: Pone un "marcador" que se define como algo a donde se puede volver en caso de error.

COMMIT: Aplica a la base de datos TODOS los cambios realizados desde el último Start Transaction (la teoría dice que si no se hace se pierden los cambios).

ROLLBACK: En caso de error DESHACE TODOS los cambios desde el último Start Transaction ejecutado.

Un ejemplo sencillo sería un cajero automático (ATM) en donde vamos a retirar dinero, tan pronto insertamos nuestra tarjeta "Inicia la Transacción", si al final de todo el proceso no se pudo entregar el dinero o se produjo algún error entonces se "reversa" la transacción con un rollback, pero en caso de ser exitosa, se aplica el Commit.

Espero haber sido claro :)

Saludos.

Sea dicho de paso que en su ejemplo, faltaría un "break" que cancelaría el ciclo (o bucle) for cuando se haga el rollback, pues así como está se produciría una excepción al tratar de hacer un segundo rollback, o al tratar de ejecutar un commit luego de haber hecho algún rollback.

Saludos.

Buenas robregonm. primero que todo, gracias por tu rapida y concisa respuesta :)

Según comentas el codigo quedaria tal que:




$transaction=Yii::app()->db->beginTransaction();

$errorSave=0;                                   

for($j=0;$j<=$z;$j++)

...

  if($model->save()){

    $errorSave=0;

  }else{

    errorSave=1;

    $transaction->rollBack();

    //añado el break

    break;

  }

}


if($errorSave==0){                                      

 $transaction->commit();

}



De esa manera se romperia el for, y como errorSave contiene un 1, el commit no se produciria… correcto?

Gracias!!!

Es correcto.Tal cual. :)

Esa es la idea.

Éxitos.