Was DU suchst - ist das was WIR gefunden haben

Was DU suchst - ist das was WIR gefunden haben

Race Conditions mit Ajax und PHP Sessions

Geschrieben von Tyler am Oktober - 27 - 2007

Ich bin auf dem Blog von Thwartedefforts auf einen interessanten Artikel zum Thema Ajax und Race Conditions gestoßen.

Race Conditions (dt. :Wettlaufsituationen) innerhalb eines Programmablauf, sind Konstellationen, in denen das Gesamtergebnis einer Operation vom zeitlichen Verhalten bestimmter Einzeloperationen abhängt.

Unbeabsichtigte oder dem Entwickler unbewusste Race Conditions führen häufig zu schwer auffindbaren Programmfehlern. Ein Indiz für die Existenz einer Race Condition ist häufig, das ein scheinbar unverändertes Testszenario bei mehren Testläufen unterschiedliche Testergebnisse liefern kann. Dies schließt das völlige verschwinden der Symptome ein.

Wenn man den Standard built-in PHP Session Handler nutzt (also den Dateibasierten) ist man vor diesem Problem geschützt. Der PHP Session Handler erstellt ein exklusives Lock auf die Session Datei (während der Lese-/Schreibzugriffs) und gibt sie nach einem erfolgreichen bearbeiten des Inhalts wieder frei. Innerhalb dieses Zeitraums ist es keinem anderen Prozess möglich auf die Session Daten zuzugreifen.

Der PHP built-in Session Handler ist für einzelne Webserver konzipiert. Möchte man seine Webserver skalieren (Load Balancer, n-Webserver) reicht ein Dateisystem basiertes Session Handling nicht mehr aus, da alle Webserver einen zentrale Session Verwaltung benötigen. Auf welchem Server der User auch landet, er muss von überall seine Session wieder aufnehmen können.

Nun kommt man nicht mehr drum herum seinen eigenen Session Handler zu implementieren.

PHP bietet die Möglichkeit über die Funktion session_set_save_handler() eigene Callbackfunktionen zum öffnen, schließen, lesen, schreiben sowie löschen und GC (Garbage Collector) zu implementieren.

Wir nehmen an, wir implementieren nun einen Datenbank basierten Session Handler.
Nun stellen wir uns einen möglichen Aufruf einer Webseite mit Ajax Elementen vor welche beim Laden der Seite aufgerufen werden.

Variante ohne Locking

Die Seite wird geladen und mehrere Ajax Elemente senden Requests an den Server. Teilweise erreichen mehrere Request innerhalb eines kurzen Zeitraum den Server und jeder Request lädt die Daten aus der Session, bearbeitet sie und schreibt sie zurück. In diesem Fall können wir innerhalb keines Requests garantieren, das die Daten, welche sich innerhalb der Session beim speichern befinden, noch die gleichen sind welche wir beim laden vorgefunden haben. Innerhalb der Bearbeitung hätte ein anderer Request die Daten innerhalb der Session verändern können.

Variante mit Locking

Die Seite wird geladen und mehrere Ajax Elemente senden Requests an den Server. Teilweise erreichen mehrere Request innerhalb eines kurzen Zeitraum den Server. Der erste Request der Daten aus der Session benötigt erstellt ein Lock auf die Session Tabelle und gibt sie nach dem session_write_close wieder frei. Dieser Vorgang wiederholt sich für jeden darauffolgenden Request. In diesem Fall können wir innerhalb jedes Requests garantieren, das die Daten, welche sich innerhalb der Session beim speichern befinden, noch die gleichen sind welche wir beim laden vorgefunden haben.

Der Artikel von Thwartedefforts gibt hier noch einen detailierten Einblick auf das Problem inklusiver einiger Bespielimplementierungen eine Datenbankbasierten Session Handlers für MySQL. Ich persönlich halte ihn für sehr gut aufbereitet und hoffe hier dem ein oder anderen ein mühseliges suchen erspart zu haben…

Hinterlass einen Kommentar

WP Cumulus Flash tag cloud by Roy Tanck requires Flash Player 9 or better.