Mysql
 sql >> Datenbank >  >> RDS >> Mysql

Wie funktionieren mysqli::commit und mysqli::rollback?

Nein, die Transaktion verfolgt nicht, wenn ein einzelnes SQL-Statement fehlschlägt.

Wenn ein einzelnes SQL-Statement die Anweisung nicht erfüllt wird zurückgesetzt (wie es in @eggyals Antwort beschrieben ist) - aber die Transaktion ist noch offen. Wenn Sie commit aufrufen Jetzt gibt es kein Rollback der erfolgreichen Anweisungen und Sie haben einfach "beschädigte" Daten in Ihre Datenbank eingefügt. Sie können dies leicht reproduzieren:

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)

Sie sehen, dass das Einfügen von 'foo' und 'bar' erfolgreich war, obwohl die zweite SQL-Anweisung fehlgeschlagen ist - Sie können sogar sehen, dass das AUTO_INCREMENT -Wert wurde durch die fehlerhafte Abfrage erhöht.

Sie müssen also die Ergebnisse jeder query überprüfen -aufrufen und falls einer fehlschlägt, rollback aufrufen um die ansonsten erfolgreichen Abfragen rückgängig zu machen. Daher macht Lorenzos Code im PHP-Handbuch Sinn.

Der einzige Fehler, der MySQL dazu zwingt, die Transaktion rückgängig zu machen, ist ein "Transaktions-Deadlock" (und das ist spezifisch für InnoDB, andere Speicher-Engines können diese Fehler anders handhaben).