Mysql
 sql >> Base de données >  >> RDS >> Mysql

Comment fonctionne mysqli::commit &mysqli::rollback ?

Non, la transaction ne suit pas si une seule instruction SQL échoue.

Si une seule instruction SQL échoue, l'instruction est annulé (comme décrit dans la réponse de @eggyal) - mais la transaction est encore ouvert. Si vous appelez commit maintenant, il n'y a pas de restauration des déclarations réussies et vous venez d'insérer des données "corrompues" dans votre base de données. Vous pouvez reproduire cela facilement :

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)

Vous voyez que l'insertion de 'foo' et 'bar' a réussi bien que la deuxième instruction SQL ait échoué - vous pouvez même voir que le AUTO_INCREMENT -la valeur a été augmentée par la requête erronée.

Vous devez donc vérifier les résultats de chaque query -call et en cas d'échec, appelez rollback pour annuler les requêtes autrement réussies. Donc le code de Lorenzo dans le manuel PHP a du sens.

La seule erreur qui force MySQL à annuler la transaction est un "blocage de transaction" (et ceci est spécifique à InnoDB, d'autres moteurs de stockage peuvent gérer ces erreurs différemment).