PHP-Entwicklung
Posts 1-6 of 6
-
Elif Kus(not a XING member)Ich habe die Sessionverwaltung auf Mysql umgestellt. In meiner Sessionklasse konfiguriere ich die session_set_save_handler-Funktionen. Meine Engine ist InnoDB und die Transaktion wird jeweils in der open() und close()-Funktion geöffnet und wieder geschlossen:15 Jul 2009, 02:10 amSession in InnoDB mit Transaktion - Kollision mit anderen Transaktionen.
class myownSessionhandler {
public function open($path, $name) {
$this->dbase->beginTransaction();
return TRUE;
}
public function close() {
$commit = $this->dbase->commit();
if(!$commit) {
$this->dbase->rollBack();
}
$this->dbase = NULL;
return TRUE;
}
//... die restlichen Funktionen read, write, destroy, gc
}
Nun möchte ich Transaktionen natürlich auch für andere Zwecke benutzen. Aber obwohl beim Aufruf von session_start() alle Funktionen des session_set_save_handler durchlaufen und auch der __desttructor aufgerufen wird, erhalte ich wenn ich eine neue Transaktion starte die folgende PDOException:
There is already an active transaction
Fatal error: Exception thrown without a stack frame in Unknown on line 0
Was mache ich falsch?
-
Post visible to registered members
-
Christian KiesewalterThe company name is only visible to registered members.Wie schon gesagt:Verschachtelte Transaktionen.15 Jul 2009, 09:33 amRe: Session in InnoDB mit Transaktion - Kollision mit anderen Transaktionen.
Wenn mit Transaktionen gearbeitet wird, kommt man eigentlich nicht drum rum für jede größere Transaktion eine eigene Datenbankverbindung aufzubauen, besonders wenn verschachtelte SQL-Zugriffe verwendet werden.
Die Session-Verbindung mit der Datenbank wird in jedem Fall als seperate Verbindung benötigt!
Die Session Verbindung bleibt für den gesamten Skriptdurchlauf (Seitenaufruf) bestehen, da ja jederzeit etwas in die Session geschrieben werden kann.
Die selbe Vorgehensweise würde aber auch Listen betreffen, wenn diese nicht mit fetchall() abgerufen werden sondern via fetch() einzeln abgearbeitet werden und zusätzliche weitere Operationen auf der Datenbank durchgeführt werden.
Über die selbe Datenbankverbindung funktioniert das nicht (zumindest nicht unter PDO). Hier muss man auch wieder über eigene Datenbankverbindungen gehen.
Ich hoffe mal das hilft ein wenig weiter.
-
Elif Kus(not a XING member)Mike Hartmann, Christian Kiesewalter!15 Jul 2009, 11:04 amRe^2: Session in InnoDB mit Transaktion - Kollision mit anderen Transaktionen.
Vielen vielen Dank! Das war unglaublich hilfreich. Ich danke Ihnen sehr, insbesondere Christian Kiesewalter, der mir das Problem ausführlich beschrieben hat.
Die Session-Verbindung mit der Datenbank wird in jedem Fall als seperate Verbindung benötigt!
Heißt das, dass ich eine seperate Datenbank anlegen muss für meine Sessions, oder einfach ein neues Objekt meiner Datenbankklasse erstellen muss? Ist es das Zweite, so wäre meine Singleton dahin. Ich habe zwar hier und da gelesen, dass eine Singleton eher ein "Teufelswerk" ist, aber so richtig begriffen hatte ich das damals nicht. Jetzt ist es überall in meinem Code.
Eine Frage noch zu PDO: seit gestern mache ich mir Gedanken darüber, ob eine Datenbankklasse überhaupt Sinn macht?! Oder ob es nicht besser ist, wenn ich das PDO-Objekt direkt erstelle, also ohne
class myDB {
public function __construct() {
try {
$db = new PDO(...);
}
catch(PDOException $e) {
throw ....
}
}
} // recht blöd ohne Highlighter
Vielen Dank für jede Hilfe.
-
Daniel JäneckeThe company name is only visible to registered members.MySQL / InnoDB beherrscht durchaus verschachtelte Transaktionen dank SAVEPOINT und ROLLBACK TO SAVEPOINT [1]. Inwieweit PDO das unterstützt weiß ich allerdings nicht.15 Jul 2009, 4:26 pmRe^3: Session in InnoDB mit Transaktion - Kollision mit anderen Transaktionen.
Allerdings sehe ich nicht so ganz warum ein Session-Handler eine Transaktion benötigt die zudem auch noch für die gesamte Zeit des Requests bestehen bleibt? Beim Start der Session wird gelesen, am Ende der Sitzung wird geschrieben; welchen Mehrwert bietet eine Transaktion?
Gruß
daniel
[1]
http://dev.mysql.com/doc/refman/5.0/en/sql-syntax-transactio...
-
Christian KiesewalterThe company name is only visible to registered members.PDO unterstützt das Ganze meines Wissens nicht.17 Jul 2009, 09:38 amRe^4: Session in InnoDB mit Transaktion - Kollision mit anderen Transaktionen.
Wenn man einen offenen Query hat, blokiert dieser komplett alle weiteren aktionen auf dieser Datenbankverbindung.
Was die eigene Datenbank-Abstraktionsklasse angeht:
Benutzt man nur eine Datenbank (MySQL) ist das Ganze relativ Witzlos, es sei denn man möchte diverse Aktionen durchführen, die ggf. über mehrere SQL-Server hinweg erfolgen müssen (Stichwort: Cluster Zugriff)
Eine andere Option ist das Erzeugen von Querys für verschiedene Datenbanksysteme -> das kann PDO nicht selber, hier muss man auch anders vorgehen.
Zur Session-Verbindung:
Heißt das, dass ich eine seperate Datenbank anlegen muss für meine Sessions, oder einfach ein neues Objekt meiner Datenbankklasse erstellen muss? Ist es das Zweite, so wäre meine Singleton dahin. Ich habe zwar hier und da gelesen, dass eine Singleton eher ein "Teufelswerk" ist, aber so richtig begriffen hatte ich das damals nicht. Jetzt ist es überall in meinem Code.
Single-was? -> Würde ich eigentlich die Finger von lassen, es sei denn es ist wirklich wichtig.
Das Singleton Entwurfsmuster braucht man je nach Projekt eigentlich extrem selten. Im prinzip nur dann, wenn man nicht irgendwelche $GLOBALS verwenden will / kann bzw. wenn es wirklich wichtig ist, dass es im gesamten Skript (also während eines Skript-Durchlaufs) ein Objekt nur einmal vorhanden ist und man einen halbwegs bequemen Weg benötigt um darauf zu zu greifen.
Bei der Datenbank kann es durchaus auch Sinn machen, allerdings stellt dies verschiedene Anforderungen an das Skript.
Die Session benötigt einen eigenen Kanal (also ein eigenes Datenbankobjekt) für die Speicherung. Man kann sie in der selben Datenbank behalten oder auch in eine andere Datenbank schreiben.
Das mit der eigenen Datenbank kann im übrigen sinnvoll sein, ist aber im Normalfall unüblich.
Ich hoffe ich hab nichts vergessen.
