Jag är glad att du inser att det bara är en dålig och tillfällig lösning och att du bör optimera din kod. Glöm dina tokens och sånt. Det enklaste och fortfarande effektiva sättet är förmodligen att ha ett exklusivt fillås på en delad fil per operation. Du kan föreställa dig det här som en träbit och bara en kan hålla ID och bara den som har det får prata eller göra något.
<?php
$fp = fopen("/tmp/only-one-bed-available.txt", "w+");
if (flock($fp, LOCK_EX)) { // do an exclusive lock
// do some very important critical stuff here which must not be interrupted:
// sleeping.
sleep(60);
echo "I now slept 60 seconds";
flock($fp, LOCK_UN); // release the lock
} else {
echo "Couldn't get the lock!";
}
fclose($fp);
?>
Om du kör det här skriptet 10 gånger parallellt kommer det att ta 10 minuter att avsluta (eftersom det bara finns en ledig säng!) och du kommer att se ekot "Jag sov nu..." var 60:e sekund (ungefär).
Detta serialiserar ALLA körningar av den här koden GLOBALT. Det här är förmodligen inte vad du vill ha (du vill ha det per användare, eller hur?) Jag är säker på att du har något liknande användar-ID, annars använd den utländska IP-adressen , och har ett unikt filnamn för varje användare:
<?php $fp = fopen("/tmp/lock-".$_SERVER["REMOTE_ADDR"].".txt", "w+"); ?>
Du kan också definiera ett låsfilnamn för en grupp operationer. Kanske kan användaren göra vissa saker parallellt men bara den här operationen skapar problem? Ge den en tagg och inkludera den i låsfilnamnet!
Denna praxis är verkligen inte så illa och kan användas! Det finns bara små sätt att göra det snabbare (mysql-intern, delat minnessegment, serialisering på ett högre lager som belastningsbalanserare...)
Med lösningen ovan kan du göra det i din applikation, vilket förmodligen är bra. Du kan använda samma schema i Mysql också:http://dev.mysql.com/doc/refman/5.0/en/miscellaneous-functions.html#function_get-lock
Men PHP-implementeringen är förmodligen enklare och bättre för ditt användningsfall.
Om du verkligen vill ha en ännu mer elegant lösning, kolla bara in den här funktionen http://www.php.net/manual/en/function.sem-get.php