Nej, transaktionen holder ikke styr, hvis en enkelt SQL-sætning fejler.
Hvis en enkelt SQL-sætning fejler sætningen er rullet tilbage (som det er beskrevet i @eggyals svar) - men transaktionen er stadig åben. Hvis du ringer til commit
nu er der ingen tilbagerulning af de vellykkede udsagn, og du har bare indsat "korrupte" data i din database. Du kan nemt gengive dette:
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)
Du kan se, at indsættelsen af 'foo' og 'bar' var vellykket, selvom den anden SQL-sætning mislykkedes - du kan endda se, at AUTO_INCREMENT
-værdien er blevet øget af den defekte forespørgsel.
Så du skal tjekke resultaterne af hver query
-kald og hvis en fejler, ring til rollback
for at fortryde de ellers vellykkede forespørgsler. Så Lorenzos kode i PHP-manualen giver mening.
Den eneste fejl, der tvinger MySQL til at rulle transaktionen tilbage, er en "transaktionsdeadlock" (og dette er specifikt for InnoDB, andre lagringsmotorer kan håndtere disse fejl anderledes).