PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Laufzeitproblem


Jezzuz
30.08.2007, 18:01:03
Hallihallo , folgendes Problemchen ...

Habe mit PHP / MySQL ein Programm zum Verwalten von Adressen geschrieben.
Habe versucht durch ein Sperrflag multiplen Zugriff azf ein und den selben Datensatz zu verhidnern :

Benutzer A fordert DS an : DS1 bekommt Sperrflag.
Benutzer B fordert DS an : Würde theoretisch durch eine mathematische Funktion DS1 bekommen, bekommt stattdessen DS2, weil DS1 ein Sperrflag gesetzt hat.

Das Flag hab ich natürlich mit einem Eintrag im Datensatz realisiert.

Das ganze funktioniert auch hervorragend, bis auf den Fall wenn 2 User exakt gleichzeitig einen neuen Datensatz anforden. Sieht so aus, als würde aus Laufzeitgründen das Flag nicht schnell genug gesetzt werden, und somit landen dann beide auf DS1, was natürlich zu tiereischen weiteren Problemen führt.

Mein Lösungsansatz: Es müsste doch für die php.ini ein Kommando geben, das quasi die komplette Abhandlung eines ClientScripts vorraussetzt um mit dem nächsten weiterzumachen. So oder so ähnlich , so dass User1 sein Flag in Ruhe setzten kann bevor DS's anforderung überhaupt eingeht.

Habe leider nix im Manual gefunden : (



Vielen Dank schon mal fürs grübeln ....

Robert

Eskayp
06.09.2007, 14:19:25
Dergleichen ist mir nicht bekannt, genau dieses Multithreading ist ja das Interessante im Produktiveinsatz.

Einen Workaround könnte man evntl. mit Hilfe von flock auf Dateien realisieren. Solange User1 also sein Flag setzt, locked er gleichzeitig eine Datei. Solange diese Datei gelocked ist, darf kein weiterer User flags setzen oder auslesen.

FabianWesner
06.09.2007, 15:26:21
Hallo Robert,

also ich denke hier kommt man an die Grenzen von PHP. Mit Java wäre das überhaubt kein Problem, aber mit PHP muss man das hinbasteln.

Ein Flag in der Datenbank ist eine gute Idee. Leider sind Schreibbefehle nicht atomar, so dass es möglich ist, dass es beim setzen des Flags zu Problemen kommt. Ich würde empfehlen für das setzen und lösen des Flags den kompletten Table mit einer Schreibsperre zu versehen, siehe http://dev.mysql.com/doc/refman/5.1/de/lock-tables.html

Also in der Reihenfolge:

LOCK TABLE (mit Schreibsperre!)
Flag setzen
UNLOCK TABLE

In aller Ruhe Daten eintragen....

LOCK TABLE (mit Schreibsperre!)
Flag löschen
UNLOCK TABLE



Die von Eskayp vorgeschlagene Alternative ist nicht besser als das Flag in der Datenbank. Hier kann es genauso zu Überlappungen kommen.

Eskayp
06.09.2007, 23:10:46
Flock ist tatsächlich nicht atomar. Das ist natürlich dumm.

Für ein "Lock Table" muss man entsprechende Rechte in der Datenbank haben. Da ich nicht weiß, ob man die überall hat, käme als Alternative das externe locking, z.B. mit Hilfe eines atomaren Flocks in Frage. Diesen könnte man übrigens über mkdir (http://de.php.net/manual/en/function.mkdir.php) simulieren (siehe Beitrag von wildcat at brightNOSPAMpages dot net auf dieser Seite (http://de.php.net/manual/en/function.flock.php)). Oder man arbeitet gleich mit Semaphoren (http://de.php.net/manual/en/ref.sem.php), sofern diese verfügbar sind.

defabricator
06.09.2007, 23:33:22
Flock ist tatsächlich nicht atomar.Hu?

FabianWesner
07.09.2007, 07:50:55
@Eskayp
Also wenn er es schafft das Modul mit den Semaphoren zu installieren, dann kann er auch den Table-Lock nutzen. Dafür muss man PHP neu comilieren. ;-)

Vor der Verwendung von flock() sollte man unbedingt die Warnung auf php.net lesen.