(MYSQL) Wie Transaktionen verwenden?
*Markus
- php
Hallo,
wie wäre die korrekte Vorgehensweise bei Transaktionen in PHP/MySQL?
mysql_query('start transaction');
//INSERT1
$query_string = "INSERT ...."
$result1 = mysql_query($query_string, $con);
//INSERT2
$query_string = "INSERT ...."
$result2 = mysql_query($query_string, $con);
($result1 && $result2) ? mysql_query('commit') : mysql_query('rollback');
if (!mysql_close($con)) {
echo "Warnung, Datenbank wurde nicht erfolgreich geschlossen: " . mysql_errno($con) . " " . mysql_error($con) . "\n";
mysql_close($con);
exit(-1);
}
Muss ich dafür die Rückgabewerte der query-Funktionen abfragen, oder weiß das PHP/MySQL auch so?
Desweiteren frage ich mich, wie man mit mysql_close() umgeht, wenn dieses nicht erfolgreich war. Einfach nochmals ausführen?
Danke,
Markus
Hi!
wie wäre die korrekte Vorgehensweise bei Transaktionen in PHP/MySQL?
Geht das mit der alten mysql-Extension von PHP? Die mysqli-Extension dürfte heutzutage überall anzutreffen sein und hat sogar eigene Funktionen für das Transaktionshandling. Auf alle Fälle benötigst du die InnoDB-Engine für die betreffenden Tabellen.
Muss ich dafür die Rückgabewerte der query-Funktionen abfragen, oder weiß das PHP/MySQL auch so?
Dafür? Wofür genau? Normalerweise sollte immer der Rückgabewert von Funktionen beachtet werden, wenn sie darüber bekanntgeben, dass Fehler auftraten.
Desweiteren frage ich mich, wie man mit mysql_close() umgeht, wenn dieses nicht erfolgreich war. Einfach nochmals ausführen?
Nach meinem (Handbuch-)Wissen kann mysql_close() nur dann false zurückgeben, wenn es keine Verbindung schließen konnte, weil entweder die übergebenen nicht offen war oder bei parameterlosem Aufruf keine entsprechende zum Schließen gefunden werden konnte. Wenn du also ein false bekommst, ignorier es oder frag dich lieber, warum die Verbindung nicht offen ist, obwohl du es angenommen hast. Da beim Scriptende sowieso alle Verbindungen geschlossen werden, ist das mit dem Per-Hand-Schließen sowieso nicht so wild.
Lo!
Hi,
wie wäre die korrekte Vorgehensweise bei Transaktionen in PHP/MySQL?
Geht das mit der alten mysql-Extension von PHP? Die mysqli-Extension dürfte heutzutage überall anzutreffen sein und hat sogar eigene Funktionen für das Transaktionshandling. Auf alle Fälle benötigst du die InnoDB-Engine für die betreffenden Tabellen.
Ja, InnoDB wird verwendet.
Muss ich dafür die Rückgabewerte der query-Funktionen abfragen, oder weiß das PHP/MySQL auch so?
Dafür? Wofür genau? Normalerweise sollte immer der Rückgabewert von Funktionen beachtet werden, wenn sie darüber bekanntgeben, dass Fehler auftraten.
das mache ich ja auch. Aber das hilft mir jetzt nicht weiter. Nochmal, wie ist Commit und Rollback zu behandeln?
Das, was in der MySQL-Doku steht ist für mich nichtssagend:
START TRANSACTION;
SELECT @A:=SUM(salary) FROM table1 WHERE type=1;
UPDATE table2 SET summary=@A WHERE type=1;
COMMIT;
Wie soll da zB Rollback ins Spiel gebracht werden? Muss ich also doch die Rückgabewerte pro SQL-Statement überprüfen und Rollback ausführen sobald eines davon false ist?
Markus
Hi!
[...] Nochmal, wie ist Commit und Rollback zu behandeln?
Das, was in der MySQL-Doku steht ist für mich nichtssagend:
Was genau hast du den gelesen? Nicht nur die Kapitel zu MySQL Transactional and Locking Statements sondern auch die zu den jeweiligen Storage Engines solltest du beachten, in deinem Fall: InnoDB Error Handling aus dem Kapitel The InnoDB Storage Engine.
Lo!
Hallo,
Was genau hast du den gelesen? Nicht nur die Kapitel zu MySQL Transactional and Locking Statements sondern auch die zu den jeweiligen Storage Engines solltest du beachten, in deinem Fall: InnoDB Error Handling aus dem Kapitel The InnoDB Storage Engine.
Ich habe es mir zwar noch nicht durchgelesen, aber ich verstehe nicht, wie mir die InnoDB-Spezifikation dabei helfen soll, Transaktionen in PHP mit MySQL logisch richtig auszuführen. Ich will schließlich keine Errorcodes abfragen, sondern nur verhindern, dass Daten dann nicht eingefügt werden, wenn bei anderen Statements Fehler auftreten.
Wenn ich 3 Abfragen habe und so etwas in die Richtung schreibe:
if ($result1 && $result2 && $result3)
mysql_query('commit');
else {
mysql_query('rollback');
mysql_close();
exit(-1);
}
müsste es meiner Meinung nach klappen.
Markus
Hi!
Ich habe es mir zwar noch nicht durchgelesen, aber ich verstehe nicht, wie mir die InnoDB-Spezifikation dabei helfen soll, Transaktionen in PHP mit MySQL logisch richtig auszuführen.
Weil MySQL, speziell die InnoDB-Engine, selbständig Rollbacks in bestimmten Situationen ausführt.
Ich will schließlich keine Errorcodes abfragen, sondern nur verhindern, dass Daten dann nicht eingefügt werden, wenn bei anderen Statements Fehler auftreten.
Ansonsten ist es deine Entscheidung, wann du einen Rollback anstößt. Wenn du dazu wissen muss, ob ein Statement einen Fehler erzeugt, dann musst du das in Erfahrung bringen und dir gegebenenfalls irgendwo merken. Solch ein Fehlerwert steht nur aktuell nach Ausführen des Statements zur Verfügung. Wenn du ein anderes Statement ausführst, weiß die MySQL-API nichts mehr vom vorhergehenden. Die Entscheidung, wann ein Rollback auszuführen ist, kann auch anhand ganz anderer Kriterien deiner Geschäftslogik getroffen werden, die nicht unbedingt einen Fehler beim Ausführen von Statements als Ursache haben müssen.
Lo!
Hallo,
Ich will schließlich keine Errorcodes abfragen, sondern nur verhindern, dass Daten dann nicht eingefügt werden, wenn bei anderen Statements Fehler auftreten.
Ansonsten ist es deine Entscheidung, wann du einen Rollback anstößt. Wenn du dazu wissen muss, ob ein Statement einen Fehler erzeugt, dann musst du das in Erfahrung bringen und dir gegebenenfalls irgendwo merken. Solch ein Fehlerwert steht nur aktuell nach Ausführen des Statements zur Verfügung. Wenn du ein anderes Statement ausführst, weiß die MySQL-API nichts mehr vom vorhergehenden. Die Entscheidung, wann ein Rollback auszuführen ist, kann auch anhand ganz anderer Kriterien deiner Geschäftslogik getroffen werden, die nicht unbedingt einen Fehler beim Ausführen von Statements als Ursache haben müssen.
Alles klar, danke. Ich glaube damit ist meine Frage beantwortet.
Markus