MySQL Lock in PHP implementieren ?

Vom einfachen Programm zum fertigen Debian-Paket, Fragen rund um Programmiersprachen, Scripting und Lizenzierung.
Antworten
Benutzeravatar
zyta2k
Beiträge: 2446
Registriert: 14.03.2003 09:18:00
Kontaktdaten:

MySQL Lock in PHP implementieren ?

Beitrag von zyta2k » 15.12.2003 17:43:27

Ahoi,

folgendes Problem (Umfrageformular App)

a) Formular wird gesendet
b) User wird Authentifiziert
c) Darf User Daten Senden ?
d) select max(user_count) from vote => $maxuser
e) $current_user=$maxuser+1
f) select max(vote_id) from vote => $maxvote
g) $current_vote=$maxvote+1
h) ... andere arbeit (zeitaufwendig !) ...
i) insert into vote(...) values ($max_vote, ..., $max_user)
j) wiederhole i für n votes

Das Problem liegt darin begraben, dass mehrere Prozesse gleichzeitig durchlaufen können und so die $max_vote und $max_user durcheinander geraten können.

Will heissen:
Prozess A schreib in die Tabelle Vote (und ist noch nicht fertig !!) währenddem Prozess B aus Tabelle Vote die max_vote ausliest und von dort weg alle Daten von Prozess A überschreibt :?

Nun... dacht ich mir, programmierst du halt einen globalen lock

Code: Alles auswählen

do {
sleep(0.1);
      $lockfile=fopen("/tmp/ubeu_submit_lockfile","r");
} while ($lockfile);
$lockfile=fopen("/tmp/ubeu_submit_lockfile","w");  // Set LOCK
a) ... j)

Code: Alles auswählen

unlink($lockfile);
Irgendwie funktioniert das ganz prächtig, wenn ich's manuell teste (file erstellen/löschen), aber wenn mehrere User drauf waren kams vor, dass sich das Sys gelockt hat und nix mehr ging (okey ich könnt einen Timer einbauen, der die Locks nach zu langem Warten einfach übergeht und löscht).
Wieso genau sich mit diesem Code ein Deadlock ergeben kann ist mir schleierhaft :/

Any Ideas ??
*thx*4help :)

Benutzeravatar
Bert
Beiträge: 3751
Registriert: 16.07.2002 14:06:52
Wohnort: Dresden
Kontaktdaten:

Beitrag von Bert » 15.12.2003 18:17:06

Das Anlegen des Locks ist nicht atomar.

Hab keiner Erfahrungen mit MySQL, aber soll MySQL mitlerweile nicht auch Transaktions unterstützen? Genau für sowas sind die ja da.
Programmer: A biological machine designed to convert caffeine into code.
xmpp:bert@debianforum.de

Benutzeravatar
godsmacker
Beiträge: 902
Registriert: 16.03.2003 21:50:26
Lizenz eigener Beiträge: Artistic Lizenz
Wohnort: Chemnitz
Kontaktdaten:

Beitrag von godsmacker » 15.12.2003 19:11:58

Bert hat geschrieben:Das Anlegen des Locks ist nicht atomar.

Hab keiner Erfahrungen mit MySQL, aber soll MySQL mitlerweile nicht auch Transaktions unterstützen? Genau für sowas sind die ja da.
Soweit ich weiß nicht. Zumindest nicht in der stable Version.
PostgreSQL hilft.

Gruß,
Florian

Benutzeravatar
Bert
Beiträge: 3751
Registriert: 16.07.2002 14:06:52
Wohnort: Dresden
Kontaktdaten:

Beitrag von Bert » 15.12.2003 19:16:12

Laut http://www.mysql.com/products/mysql/index.html schon (mit InnoDB ). Ob das in der Woody Version schon bei ist, weiß ich nicht. Obwohl das nicht wirklich neu ist.
Programmer: A biological machine designed to convert caffeine into code.
xmpp:bert@debianforum.de

Benutzeravatar
zyta2k
Beiträge: 2446
Registriert: 14.03.2003 09:18:00
Kontaktdaten:

Beitrag von zyta2k » 15.12.2003 22:04:54

Bert hat geschrieben:Laut http://www.mysql.com/products/mysql/index.html schon (mit InnoDB ). Ob das in der Woody Version schon bei ist, weiß ich nicht. Obwohl das nicht wirklich neu ist.
InnoDB ist erst ab Version 4 :?

Woody d.h. Server ist ein 3er SQL :(

Und der Switch zu PostgreSQL ist wohl auch nicht so schnell machbar :?

Benutzeravatar
zyta2k
Beiträge: 2446
Registriert: 14.03.2003 09:18:00
Kontaktdaten:

Beitrag von zyta2k » 16.12.2003 12:26:25

Andere Frage:

Wenn ich nun eine Variable definiere und die in dem sleep while hochzähle:

Wird diese für jeden Prozess neu definiert oder greifen alle Prozesse auf dieselbe Variable zu ?

Will heissen, würden sie sich die Variable gegenseitig hochzählen ?

Sonst lös ich's nämlich tatsächlich mit einem emergency counter der e.g. auf 20 Zählt (würde 2sek entsprechen bei sleeps von 0.1sek) und dann den lock löscht/übergeht.

Benutzeravatar
hupf
Beiträge: 113
Registriert: 20.06.2002 21:15:44
Wohnort: Biel/Bienne, CH

Beitrag von hupf » 16.12.2003 13:18:28

übrigens gerade im neusten iX heft hats einen interessanten artikel über transaktionen in mysql:

Sandro Zic (ck)
Sichere Schiebereien
Transaktionen in MySQL benutzen
iX 12/03, Seite 119

Benutzeravatar
hupf
Beiträge: 113
Registriert: 20.06.2002 21:15:44
Wohnort: Biel/Bienne, CH

Beitrag von hupf » 16.12.2003 13:26:23

ach und sonst könntest du ja in php semaphoren implementieren ;)

Benutzeravatar
zyta2k
Beiträge: 2446
Registriert: 14.03.2003 09:18:00
Kontaktdaten:

Beitrag von zyta2k » 16.12.2003 14:04:00

hupf hat geschrieben:ach und sonst könntest du ja in php semaphoren implementieren ;)
Schön.
Dazu muss ich aber wissen, wie PHP Variablen handlet :?

Pro Prozess (bzw. User) eine eigene Variable oder werden diese geshared ?

Benutzeravatar
zyta2k
Beiträge: 2446
Registriert: 14.03.2003 09:18:00
Kontaktdaten:

Beitrag von zyta2k » 16.12.2003 16:10:31

*mirandenkopfpatsch*

Wieso nicht das benutzen was PHP bietet ?? *gg*

Code: Alles auswählen

<?php
// gemeinsames Speichersegment beschaffen
if(! ($mkey = shm_attach(0x2328,1024,OctDec("666"))))
{ echo "shmem_attach fehlgeschlagen<br>\n"; exit;}

// Semaphor für Zugriffskoordination auf
// Speichersegment beschaffen
if(! ($skey = sem_get(0x2328,1,OctDec("666"))))
{ echo "sem_get fehlgeschlagen<br>\n"; exit;}

// Zugriff anfordern
if(! sem_acquire($skey))
{ echo "sem_acquire fehlgeschlagen<br>\n"; exit;}

// 
// Der "geschützte Code" kommt hier ;)
// 

// Zugriff freigeben
sem_release($skey);
?> 

Benutzeravatar
hupf
Beiträge: 113
Registriert: 20.06.2002 21:15:44
Wohnort: Biel/Bienne, CH

Beitrag von hupf » 16.12.2003 17:30:27

hey, gar nicht gewusst, dass es das gibt! toller ansatz... :D

Andreas Diem
Beiträge: 23
Registriert: 18.09.2002 18:29:02
Wohnort: Neubau
Kontaktdaten:

Beitrag von Andreas Diem » 16.12.2003 18:28:36

zyta2k hat geschrieben:
Bert hat geschrieben:Laut http://www.mysql.com/products/mysql/index.html schon (mit InnoDB ). Ob das in der Woody Version schon bei ist, weiß ich nicht. Obwohl das nicht wirklich neu ist.
InnoDB ist erst ab Version 4 :?

Woody d.h. Server ist ein 3er SQL :(

Und der Switch zu PostgreSQL ist wohl auch nicht so schnell machbar :?
InnoDB gibt es ab Version 3.23.34a, in der Woody Version ist InnoDB vorhanden.
InnoDB ist aber deaktiviert skip-innodb.
http://www.mysql.de/doc/de/InnoDB_overview.html

Ab Version 4 werden Transaktion auch bei ISAM unterstütz.
mfg
Andreas Diem
webmaster@andreas-diem.at

Antworten