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).