Nej, transaktionen håller inte reda på om ett enda SQL-uttalande misslyckas.
Om en enda SQL-sats misslyckas med satsen rullas tillbaka (som det beskrivs i @eggyals svar) - men transaktionen är fortfarande öppen. Om du ringer commit
nu finns det ingen återställning av de framgångsrika uttalandena och du har bara infogat "skadad" data i din databas. Du kan enkelt återskapa detta:
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 ser att infogningen av 'foo' och 'bar' lyckades även om den andra SQL-satsen misslyckades - du kan till och med se att AUTO_INCREMENT
-värdet har ökats av den felaktiga frågan.
Så du måste kontrollera resultaten av varje query
-ringa och om ett misslyckas, ring rollback
för att ångra de annars lyckade frågorna. Så Lorenzos kod i PHP-manualen är vettig.
Det enda felet som tvingar MySQL att återställa transaktionen är ett "transaktionsstopp" (och detta är specifikt för InnoDB, andra lagringsmotorer kan hantera dessa fel på ett annat sätt).