Autor
|
Tema: [solucionado] mysqli rollback todos los insert si uno falla (Leído 3,043 veces)
|
gAb1
Desconectado
Mensajes: 731
|
Tengo un script que sube datos a diferentes tablas mysql y necesito que si un insert falla, no se haga ninguno. Para ello he estado leyendo y creo tener una idea clara: $mysqli = new mysqli(/* datos de conexión */); $mysqli->autocommit(FALSE); // el rollback lo dejará todo como estaba aquí $mysqli->begin_transaction(); if ($stmt_uno = $mysqli->prepare('INSERT INTO tabla_principal (uno, dos, tres) VALUES (?, ?, ?)')) { $stmt_uno->bind_param('sss', $uno, $dos, $tres); $stmt_uno->execute(); $id = (int) $mysqli->insert_id; if ($stmt_dos = $mysqli->prepare('INSERT INTO sub_tabla (principal_id, cuatro) VALUES (?, ?)')) { $stmt_dos->bind_param('is', $id, $cuatro); $stmt_dos->execute(); } if ($stmt_tres = $mysqli->prepare('INSERT INTO sub_tabla_dos (principal_id, cinco) VALUES (?, ?)')) { $stmt_tres->bind_param('is', $id, $cinco); $stmt_tres->execute(); } } if ($mysqli->commit()) { // todo correcto, se redirige } else { // algo ha salido mal, se llama rollback $mysqli->rollback(); // y se muestra un mensaje de error }
Todavía no lo he probado, pero no estoy seguro de si es así o hay que comprobar cada execute()... ¿Alguien puede corregirme? Gracias! Edito: cambio la estructura, el resto de inserts dependen del primero, pero si cualquiera falla no debe insertarse nada.
|
|
« Última modificación: 12 Abril 2016, 02:35 am por gAb1 »
|
En línea
|
|
|
|
Gallu
Desconectado
Mensajes: 247
|
Hola, lo mejor en estos casos es usar bloques try catch. http://php.net/manual/es/language.exceptions.phpDe esta forma te aseguras de que ante cualquier error se ejecute el rollback Por ejemplo: $mysqli = new mysqli(/* datos de conexión */); $mysqli->autocommit(FALSE); // el rollback lo dejará todo como estaba aquí $mysqli->begin_transaction(); try{ if ($stmt_uno = $mysqli->prepare('INSERT INTO tabla_principal (uno, dos, tres) VALUES (?, ?, ?)')) { $stmt_uno->bind_param('sss', $uno, $dos, $tres); $stmt_uno->execute(); $id = (int) $mysqli->insert_id; if ($stmt_dos = $mysqli->prepare('INSERT INTO sub_tabla (principal_id, cuatro) VALUES (?, ?)')) { $stmt_dos->bind_param('is', $id, $cuatro); $stmt_dos->execute(); } if ($stmt_tres = $mysqli->prepare('INSERT INTO sub_tabla_dos (principal_id, cinco) VALUES (?, ?)')) { $stmt_tres->bind_param('is', $id, $cinco); $stmt_tres->execute(); } } if ($mysqli->commit()) { // todo correcto, se redirige } }catch(Exception $error){ //deshacemos todo $mysqli->rollback(); echo 'Excepción capturada: ', $error->getMessage(), "\n"; }
|
|
|
En línea
|
Nadie alcanza la meta con un solo intento, ni perfecciona la vida con una sola rectificación, ni alcanza altura con un solo vuelo.
|
|
|
gAb1
Desconectado
Mensajes: 731
|
Ah, al fin algo nuevo. Si que son muy utiles esos blockes. Gracias, dejo como lo he hecho: $mysqli = new mysqli(/* datos de conexión */); $mysqli->autocommit(FALSE); // el rollback lo dejará todo como estaba aquí $mysqli->begin_transaction(); try{ if ($stmt_uno = $mysqli->prepare('INSERT INTO tabla_principal (uno, dos, tres) VALUES (?, ?, ?)')) { $stmt_uno->bind_param('sss', $uno, $dos, $tres); if (!$stmt->execute()) { throw new Exception($stmt->error); } $id = (int) $mysqli->insert_id; if ($stmt_dos = $mysqli->prepare('INSERT INTO sub_tabla (principal_id, cuatro) VALUES (?, ?)')) { $stmt_dos->bind_param('is', $id, $cuatro); if (!$stmt->execute()) { throw new Exception($stmt->error); } } if ($stmt_tres = $mysqli->prepare('INSERT INTO sub_tabla_dos (principal_id, cinco) VALUES (?, ?)')) { $stmt_tres->bind_param('is', $id, $cinco); if (!$stmt->execute()) { throw new Exception($stmt->error); } } } if ($mysqli->commit()) { $redirect = TRUE; } else { throw new Exception('Transaction commit failed. Property ID: ' . $id); } } catch (Exception $e) { try { $mysqli->rollback(); $err_msg = $e->getMessage(); } catch (Exception $f) { $err_msg = $f->getMessage(); } } // es importante volver a activar el autocommit $mysqli->autocommit(TRUE);
Me costó un buen rato darme cuenta de por qué no se guardaba nada en la db
|
|
|
En línea
|
|
|
|
|
Mensajes similares |
|
Asunto |
Iniciado por |
Respuestas |
Vistas |
Último mensaje |
|
|
[Solucionado] Problema con bulk insert
Bases de Datos
|
criskapunk
|
0
|
8,541
|
16 Junio 2011, 14:59 pm
por criskapunk
|
|
|
[Solucionado] Falla conexión al inicio
GNU/Linux
|
WifliX
|
7
|
5,136
|
3 Octubre 2012, 18:53 pm
por Lecter21
|
|
|
SQLite3 INSERT INTO + EXCEPT [SOLUCIONADO]
Bases de Datos
|
patilanz
|
4
|
4,406
|
5 Octubre 2015, 21:11 pm
por patilanz
|
|
|
Mysqli error ayuda [ SOLUCIONADO ]
Desarrollo Web
|
noobcoder
|
3
|
3,131
|
20 Marzo 2016, 18:46 pm
por noobcoder
|
|
|
[Resuelto] mysqli rollback deja de funcionar en php 7
PHP
|
gAb1
|
1
|
2,991
|
8 Junio 2016, 18:22 pm
por gAb1
|
|