Raketenwilli: Nachtrag: PHP, MySQL Abbruch vermeiden

Beitrag lesen

Boah! Muss man hier wieder GENAU sein…

Hallo Raketenwilli,

ROLLBACK-Kommando

Ist PHP automatisch transaktional?

PHP an sich kann es nicht sein, denn „(nicht) transaktional“ ist eine Eigenschaft von DatenBank(ManagementSystemen) - genauer gesagt, der verwendeten Speicher-Engine. Immerhin können sogar einzelne, große Transaktionen durchaus auch sehr viel mehr Platz brauchen als der Arbeitsspeicher bietet…

MySQL/MariuaDB können Transaktionen, sind also prinzipiell „transaktional“ (s.o.), starten für jede Sitzung auch automatisch eine Transaktion - haben aber einen aktiven autocommit, so dass alle Änderungen sofort „committed“ (von der sitzungsprivaten Transaktion in den Hauptspeicher der Datenbank übertragen und damit für alle anderen Sitzungen sichtbar) werden:

→ Auch PHP „baut“ als Client mit PDO oder mysqli eine solche Sitzung - womit die Datenbank die Transaktion also eröffnet - eber eben auch jede Änderung sofort comittet.

Man kann das abschalten (autocommit=0, s.u.) oder eine Transaktion in der Transaktion starten - das ist es was das PHP Handbuch vorschlägt, wobei die Beschreibung für PHP-PDO eigentlich sogar falsch ist:

PHP::PDO:

https://www.php.net/manual/de/pdo.begintransaction.php

„Deaktiviert den Autocommit-Modus. Wenn der Autocommit-Modus deaktiviert ist, werden Änderungen, die über die Instanz eines PDO-Objekts an der Datenbank vorgenommen werden, erst dann bestätigt, wenn die Transaktion durch den Aufruf von PDO::commit() beendet wird.“

Das ist falsch, denn das startet tatsächlich eine Transaktion in der Transaktion - nur eben ohne autocommit.

Die Beschreibung für PHP::mysqli klingt ähnlich, ist aber nicht so falsch:

https://www.php.net/manual/de/mysqli.begin-transaction.php

„Beginnt eine Transaktion; benötigt die InnoDB-Engine“

Beginnt eine Transaktion in der Transaktion - auch ohne autocommit.

Das gilt freilich nur dann wenn die gewählte oder automatisch gesetzte Speicher-Engine Transaktionen unterstützt... Das seit Jahren als default benutzte InnoDB tut es.

In der Mysql/MariaDB-Shell erreicht man das, in dem man vor den nicht automatisch zu „comittenden“ Aktionen einmalig mit

SET autocommit=0;

die Variable setzt. Das geht freilich auch von PHP aus. Als ganz normale SQL-Anweisung…

Danach werden die Änderungen erst nach einem explizitem COMMIT in den übrigen Sitzungen sichtbar bzw. beim Beenden übernommen. Wenn es bei schreibenden Zugriffen darauf ankommt, dass eine ganze Gruppe solcher Aktionen entweder übernommen wird oder nicht, ist das Deaktivieren des autocommits - für die übrigens stets mit jeder Sitzung automatisch (im Hintergrund) gestartete Transaktion - die beste Idee.

Man kann Transaktionen sogar selbst verschachteln und ihnen Spitznamen geben...