Ne, transakce nesleduje, pokud selže jeden příkaz SQL.
Pokud jeden příkaz SQL selže, příkaz je vrácena zpět (jak je popsáno v @eggyal's Answer) – ale transakce je stále otevřená. Pokud zavoláte commit
nyní nedochází k žádnému vrácení úspěšných příkazů a do databáze jste pouze vložili "poškozená" data. Můžete to snadno reprodukovat:
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)
Vidíte, že vložení 'foo' a 'bar' bylo úspěšné, i když druhý příkaz SQL selhal – můžete dokonce vidět, že AUTO_INCREMENT
-hodnota byla zvýšena chybným dotazem.
Takže musíte zkontrolovat výsledky každého query
-call a pokud jeden selže, zavolá rollback
vrátit zpět jinak úspěšné dotazy. Takže Lorenzův kód v PHP-manuálu dává smysl.
Jediná chyba, která nutí MySQL vrátit transakci zpět, je „zablokování transakce“ (a to je specifické pro InnoDB, jiné úložné stroje mohou tyto chyby zpracovat jinak).