[MySQL] Frage zum Sperren von Tabellen

theHacker

sieht vor lauter Ads den Content nicht mehr
Teammitglied
ID: 69505
L
20 April 2006
22.682
1.316
'n Abend.

Ich habe gerade etwas ausgetüfftelt, möchte mir aber vorher noch mal ne Bestätigung einholen, dass das auch wirklich funktioniert, wie ich mir das vorstelle.

Die Situation vereinfacht:
Ich habe eine Tabelle, in der ich ein Flag setzen kann. Ist es gesetzt ("Spalte hat den Wert 1"), soll das Script eine bestimmte Aktion ausführen und das Flag löschen (die Spalte also wieder auf 0 setzen). Ist es nicht gesetzt, dann eben nicht.
Wichtig ist, dass die Aktion nur genau einmal ausgeführt werden darf !

Rufen 2 Clienten gleichzeitig das Script auf, hätte ich ja sonst das Problem, dass beide den Wert 1 lesen und beide die Aktion ausführen, was nicht gewünscht ist.

Seh ich das richtig, dass ich mit
Code:
[FONT=Courier New][B][COLOR=DarkOrchid]LOCK TABLES[/COLOR][/B] `mytable` [B][COLOR=DarkOrchid]WRITE[/COLOR][/B][COLOR=black];[/COLOR][B][COLOR=DarkOrchid]
[/COLOR][/B][/FONT][FONT=Courier New][I][COLOR=DarkOrange]# ^-- ab hier warten andere Clienten, sollten sie
# auch LOCK TABLES oder SELECT ausführen wollen[/COLOR][/I][/FONT][FONT=Courier New][B][COLOR=DarkOrchid]
SELECT[/COLOR][/B] `flag` [B][COLOR=DarkOrchid]FROM [/COLOR][/B]`mytable`[/FONT][FONT=Courier New][COLOR=black];[/COLOR][/FONT][FONT=Courier New][I][COLOR=DarkOrange]
# hier in PHP flag auswerten und sichern[/COLOR][/I]
[B][COLOR=DarkOrchid]UPDATE[/COLOR][/B] `mytable` [B][COLOR=DarkOrchid]SET [/COLOR][/B]`flag`=0[/FONT][FONT=Courier New][COLOR=black];[/COLOR][/FONT][FONT=Courier New] [I][COLOR=DarkOrange]# wenn Flag gesetzt, resetten[/COLOR][/I]
[B][COLOR=DarkOrchid]UNLOCK TABLES[/COLOR][/B][/FONT][FONT=Courier New][COLOR=black];[/COLOR][/FONT][FONT=Courier New]
[I][COLOR=DarkOrange]# in aller Ruhe die Aktion durchführen, falls flag gesetzt war[/COLOR][/I][/FONT]
die korrekte Lösung habe ?

Manual-Link:
https://dev.mysql.com/doc/refman/5.1/en/lock-tables.html
 
du musst nen read lock setzen ansonsten bringt das null punkte...
Das musst du mir aber erklären, warum.

Das Manual spricht:
If a thread obtains a READ lock on a table, that thread (and all other threads) can only read from the table. If a thread obtains a WRITE lock on a table, only the thread holding the lock can write to the table. Other threads are blocked from reading or writing the table until the lock has been released.
Wenn ich nur eine READ-Sperre draufleg, können andere ja immer noch von der Tabelle lesen und es ist möglich, dass zwei Leute gleichzeitig, die 1 auslesen.
Bei einer WRITE-Sperre werden andere Threads vom Lesen abgehalten, was den gewünschten Effekt bringt. Nur der, der die Sperre hat, kann das gesetzte Flag lesen und es wieder resetten, noch ehe ein anderer es lesen kann.

Wo ist mein Denkfehler ?
 
der code ist so korrekt, denk aber dran, das du u.U große Qeues aufbauen kannst, wenn viele gleichzeitig lesen wollen. Alternativ kann dir vllt der TabellenTyp InnoDB helfen, der ein zeilenweises Locking einsetzt und nicht tabellenweise wie MyIsam
 
Jep, entweder InnoDB oder das Konzept überdenken. Womöglich kannst du das gleiche ohne eine Tabellensperre bewirken? Ich hatte jedenfalls viele Situationen, die ich anders umgehen konnte, da Tabellensperren u.U. das ganze total blocken können, wenn was schief läuft. Wenn du willst, kannst du ja ein paar Details mehr posten, was das ganze macht ... vielleicht kann ich dir paar Tipps geben :)