mehrere mysql_query mit LOCK TABLES

dwex

Erfahrenes Mitglied
Hallo Leute,

ich muss aus einer DB eine Zahl auslesen, verarbeiten, dieser dann 1 dazu zählen und wieder in der DB speichern.

Jetzt habe ich mir gedacht, da es ja sein kann, dass wärend des verarbeitens jemand anderes auf diese Zahl zugreift und verändert und somit mein DB-Eintrag am Schluss nicht mehr stimmt.

Jetzt habe ich (verkürzt) folgenden Code:
PHP:
mysql_query("LOCK TABLES nummernkreise READ");

$abfrage = mysql_query("SELECT * FROM `nummernkreise` WHERE `jahr` = '".$berechnetes_jahr."' LIMIT 1");

$daten = mysql_fetch_array($abfrage);

// einige berechnungen mit der zahl $daten['zaehler']
// einige if´s und else´s
// einige weitere mysql_query´s

mysql_query("UPDATE `nummernkreise` SET `zaehler` = '".$neuer_zaehler."' WHERE `jahr` = '".$berechnetes_jahr."' LIMIT 1");

mysql_query("UNLOCK TABLES");
Wenn ich nun an das Update komme erhalte ich von MySQL eine Fehlermeldung nach dem Motto: du kannst die Tabelle nicht updaten weil du Sie zum lesen gesperrt hast.

Kann mir jemand einen praktikablen Weg aufzeigen wie man das realisieren könnte ohne das zwischen meinen Abfragen (sind mehrere) dazwischen gefunkt wird?

Vielen Dank im voraus!
 
Wenn du InnoDB benutzt, ließe sich das wohl mit Transaktionen lösen. Aber darauf gehe ich nicht näher ein, weil es für dein Problem eine viel trivialere Lösung gibt. Lass diesen LOCK Kram weg und machen folgendes

PHP:
mysql_query("UPDATE `nummernkreise` SET `zaehler` = $neuer_zaehler WHERE `jahr` = $berechnetes_jahr AND `zaehler` = $alter_zaehler");

Wenn du jetzt prüfst, ob ein Datensatz verändert wurde (mysql_affected_rows), weißt du, dass in der Zwischenzeit niemand den Wert verändert hat. Falls mysql_affected_rows 0 liefert, musst du entsprechend darauf reagieren und z.B. den Wert neu auslesen und die Berechnungen erneut durchführen. Das heißt du könntest den ganzen Code in eine Schleife stecken.

PHP:
do {
    //Hier das Auslesen, deine Berechnungen und das Update
} while(!mysql_affected_rows($foo));
 
Zurück