sql >> Databáze >  >> RDS >> Mysql

Jak funguje mysqli::commit &mysqli::rollback?

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).



  1. Jak zabezpečit MySQL:Část první

  2. Komunikace s databází Android a Mysql

  3. PostgreSQL dotaz je pomalý při použití NOT IN

  4. Přejmenování tabulky oddílů automaticky v ORACLE