ejemplo - PHP, MySQL, PDO Transactions-¿El código dentro try try stop en commit()?
php pdo rollback (3)
La ejecución se detiene cuando se lanza una excepción.
No se alcanzará la primera devolución, pero se ejecutará la declaración de captura.
Incluso puede devolver el compromiso directamente:
$dbh->beginTransaction();
try {
// insert/update query
return $dbh->commit();
} catch (PDOException $e) {
$dbh->rollBack();
return false;
}
Soy bastante nuevo en las transacciones.
Antes, lo que estaba haciendo era algo así como:
Código Bloque 1
$db = new PDO(...);
$stmt = $db->prepare(...);
if($stmt->execute()){
// success
return true;
}else{
// failed
return false;
}
Pero en un intento de agrupar múltiples consultas en una sola transacción, ahora estoy usando algo como:
Código Bloque 2
$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$db->beginTransaction();
try{
$stmt = $db->prepare(... 1 ...);
$stmt->execute();
$stmt = $db->prepare(... 2 ...);
$stmt->execute();
$stmt = $db->prepare(... 3 ...);
$stmt->execute();
$db->commit();
return true;
}catch(Exception $e){
// Failed, maybe write the error to a txt file or something
$db->rollBack();
return false;
}
Mi pregunta es: si la transacción falla por alguna razón, el código se detiene en $db->commit();
y saltar al bloque de catch
? O el return true;
sería return true;
correr primero, y luego trataría de ir a la catch
? Porque si ese es el caso, entonces ya he regresado, y por lo tanto no iría al catch
. Y hubiera devuelto el valor equivocado.
¿Todavía necesito incluir algo como:
Bloque de código 3
if($stmt->commit()){
return true;
}
o es suficiente de la forma en que lo tengo escrito en el Bloque de Código 2 ?
Si enfrenta un error, puede hacer esto para deshacer todas las transacciones como esta
catch(Exception $e){
$db->rollBack();
// Failed, maybe write the error to a txt file or something
return false;
}
Si la transacción falla por alguna razón, el código se detiene en la misma línea donde ocurrió el error y luego la ejecución salta directamente al bloque catch. Por lo tanto, es suficiente la forma en que lo tiene escrito en el Bloque de código 2.
Tenga en cuenta que siempre debe volver a lanzar la excepción después de la reversión. De lo contrario, nunca tendrás una idea de lo que era un problema. Entonces debería ser
try{
$stmt = $db->prepare(... 1 ...);
$stmt->execute();
$stmt = $db->prepare(... 2 ...);
$stmt->execute();
$stmt = $db->prepare(... 3 ...);
$stmt->execute();
$db->commit();
return true;
}catch(Exception $e){
$db->rollBack();
throw $e;
}