sql >> Base de Datos >  >> RDS >> Mysql

¿Cómo funciona mysqli::commit y mysqli::rollback?

No, la transacción no realiza un seguimiento si falla una sola instrucción SQL.

Si una sola instrucción SQL falla, la instrucción se revierte (como se describe en la respuesta de @eggyal), pero la transacción todavía está abierto. Si llamas a commit ahora, no hay reversión de las declaraciones exitosas y simplemente insertó datos "corruptos" en su base de datos. Puedes reproducir esto fácilmente:

m> CREATE TABLE transtest (id INT NOT NULL PRIMARY KEY AUTO_INCREMENT,
 name VARCHAR(100) NOT NULL DEFAULT '',
 CONSTRAINT UNIQUE KEY `uq_transtest_name` (name)) ENGINE=InnoDB;
Query OK, 0 rows affected (0.07 sec)

m> START TRANSACTION;
Query OK, 0 rows affected (0.00 sec)

m> INSERT INTO transtest (name) VALUE ('foo');
Query OK, 1 row affected (0.00 sec)

m> INSERT INTO transtest (name) VALUE ('foo');
ERROR 1062 (23000): Duplicate entry 'foo' for key 'uq_transtest_name'

m> INSERT INTO transtest (name) VALUE ('bar');
Query OK, 1 row affected (0.00 sec)

m> COMMIT;
Query OK, 0 rows affected (0.02 sec)

m> SELECT * FROM transtest;
+----+------+
| id | name |
+----+------+
|  3 | bar  |
|  1 | foo  |
+----+------+
2 rows in set (0.00 sec)

Verá que la inserción de 'foo' y 'bar' fue exitosa aunque la segunda instrucción SQL falló; incluso puede ver que el AUTO_INCREMENT -el valor se ha incrementado por la consulta defectuosa.

Por lo tanto, debe verificar los resultados de cada query -llamar y si uno falla, llamar a rollback para deshacer las consultas exitosas. Así que el código de Lorenzo en el manual de PHP tiene sentido.

El único error que obliga a MySQL a revertir la transacción es un "bloqueo de transacción" (y esto es específico de InnoDB, otros motores de almacenamiento pueden manejar esos errores de manera diferente).