Ey! Ik ben bezig een systeem op te zetten in PHP icm MySQL (innodb) dat door veel mensen tegelijkertijd gebruikt gaat worden. Tot dusver heb ik nooit met transactions of table/row locking gewerkt, maar ik kwam gister tot de conclussie dat dit nodig gaat zijn. Na wat gezocht te hebben kreeg ik niet echt een concreet antwoord, dus heb ik m'n eigen 'lock' functie geschreven, versimpeld:
do { $result = query("INSERT INTO table_lock (table, row_id, timestamp) VALUES (..)");} while ($result == false);
Zo blijven alle scripts naast elkaar draaien en duurt het af en toe wat langer om te lock te krijgen. Als de insert succesvol is is de lock gemaakt en gaat het script verder; om de lock te verwijderen delete ik de row weer. Ik sla de timestamp op om deadlocks te voorkomen (lock mag max. 2 seconde duren).
Nu werkt dit allemaal wel redelijk netjes. Nadeel is dat er bij veel threads constant een 'insert'-fest bezig is die allemaal gruwelijk falen zolang er al een lock is; lijkt me niet erg efficient. Ik doe nu een usleep(50000) tussen de inserts en heb van table_lock een memory-tabel gemaakt om het wat te beperken, maar dat is maar behelpen natuurlijk.
De vraag dus: is er een betere manier om dit te bereiken? De bedoeling is dus dat zolang 1 record gelockt is geen enkel ander script dat record mag lezen of schrijven. De lock wordt altijd binnen hetzelfde script gemaakt en verwijdert (en zal dus nooit lang bestaan). Als er een lock is moeten de andere scripts geen foutmelding krijgen, maar even 'on hold' blijven staan.
do { $result = query("INSERT INTO table_lock (table, row_id, timestamp) VALUES (..)");} while ($result == false);
Zo blijven alle scripts naast elkaar draaien en duurt het af en toe wat langer om te lock te krijgen. Als de insert succesvol is is de lock gemaakt en gaat het script verder; om de lock te verwijderen delete ik de row weer. Ik sla de timestamp op om deadlocks te voorkomen (lock mag max. 2 seconde duren).
Nu werkt dit allemaal wel redelijk netjes. Nadeel is dat er bij veel threads constant een 'insert'-fest bezig is die allemaal gruwelijk falen zolang er al een lock is; lijkt me niet erg efficient. Ik doe nu een usleep(50000) tussen de inserts en heb van table_lock een memory-tabel gemaakt om het wat te beperken, maar dat is maar behelpen natuurlijk.
De vraag dus: is er een betere manier om dit te bereiken? De bedoeling is dus dat zolang 1 record gelockt is geen enkel ander script dat record mag lezen of schrijven. De lock wordt altijd binnen hetzelfde script gemaakt en verwijdert (en zal dus nooit lang bestaan). Als er een lock is moeten de andere scripts geen foutmelding krijgen, maar even 'on hold' blijven staan.