Nee, de transactie wordt niet bijgehouden als een enkele SQL-statement mislukt.
Als een enkele SQL-instructie niet voldoet aan de instructie wordt teruggedraaid (zoals beschreven in het antwoord van @eggyal) - maar de transactie staat nog steeds open. Als je commit
. belt nu is er geen terugdraaiing van de succesvolle verklaringen en hebt u zojuist "beschadigde" gegevens in uw database ingevoegd. U kunt dit eenvoudig reproduceren:
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)
U ziet dat het invoegen van 'foo' en 'bar' succesvol was, hoewel de tweede SQL-instructie is mislukt - u kunt zelfs zien dat de AUTO_INCREMENT
-waarde is verhoogd door de foutieve zoekopdracht.
U moet dus de resultaten van elke query
. controleren -bel en als er een faalt, bel dan rollback
om de anders succesvolle zoekopdrachten ongedaan te maken. De code van Lorenzo in de PHP-handleiding is dus logisch.
De enige fout die MySQL dwingt om de transactie terug te draaien is een "transactie impasse" (en dit is specifiek voor InnoDB, andere opslag-engines kunnen die fouten anders behandelen).