Não, a transação não acompanha se uma única instrução SQL falhar.
Se uma única instrução SQL falhar na instrução é revertida (como descrito na resposta de @eggyal) - mas a transação ainda está aberto. Se você chamar
commit
agora, não há rollback das declarações bem-sucedidas e você acabou de inserir dados "corrompidos" em seu banco de dados. Você pode reproduzir isso facilmente: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)
Você vê que a inserção de 'foo' e 'bar' foi bem-sucedida, embora a segunda instrução SQL tenha falhado - você pode até ver que o
AUTO_INCREMENT
-valor foi aumentado pela consulta defeituosa. Então você tem que verificar os resultados de cada
query
-call e se um falhar, chame rollback
para desfazer as consultas bem-sucedidas. Portanto, o código de Lorenzo no manual do PHP faz sentido. O único erro que força o MySQL a reverter a transação é um "impasse de transação" (e isso é específico do InnoDB, outros mecanismos de armazenamento podem lidar com esses erros de maneira diferente).