|
|
#1 (permalink) | ||||||
|
Erfahrener Benutzer
|
Hallo,
ich entwickel gerade ein Script und habe folgendes Problem: In einem Schritt möchte ich aus einer Datenbank einen bestimmten Eintrag auswählen. Jeder Eintrag hat einen Status (0...3) und der ausgewählte Eintrag soll den Status 0 haben. Direkt danach ändere ich in einem zweiten Schritt den Status auf 1. Wie löse ich das am klügsten, ohne das während Schritt 1 und Schritt 2 eine Race Condition auftreten kann? Meine SQL Statements sehen aktuell wie folgt aus: Schritt 1: Code:
Code:
Gruß Carny arbeitsrechtanwalt.info | primera-division.com | Sportwetten mit Bonus
Mein Seo Blog | sportwettentipps.de |
||||||
|
|
|
| Gesponsorte Links |
|
|
#4 (permalink) | |||
|
Erfahrener Benutzer
|
Also sähe eine Beispiellösung so aus:
Code:
Gruß Carny arbeitsrechtanwalt.info | primera-division.com | Sportwetten mit Bonus
Mein Seo Blog | sportwettentipps.de |
|||
|
|
|
|
#7 (permalink) | |||||
|
return void
|
Zitat:
Datenbanken wie MySQL verwenden MVCC, jede Transaktion sieht also einen konsistenten Snapshot der gesamten Datenbank der bei Beginn der Transaktion definiert wird. Aus diesem Grunde ist kein Locking für Reads mehr nötig (im Gegensatz zu den definierten Isolation Levels von ANSI-SQL), ein Read wird also nie irgendwelche Daten locken, weder shared noch exklusiv. Erst beim Schreiben von Daten werden Daten gelockt, das ist aber für das Beispiel von Carny schon zu spät. Zitat:
SELECT ... FOR UPDATE und SELECT ... LOCK IN SHARE MODE, super Mysql, noch inkonsistenter kann man die Kommandos nicht bennen |
|||||
|
|
|
|
|
#8 (permalink) |
|
Erfahrener Benutzer
|
Ok hab mir Select For Update jetzt mal genauer angeschaut. Wie bereits erwähnt ist mir das alles noch etwas unklar, aber ich versuch das mal etwas zu erklären.
Soweit ich das verstanden habe, wird bei diesem SQL Befehl eine Zeile aus der Datenbank bis zum nächsten Update gesperrt (für lesen oder schreiben gesperrt??). Was genau passiert jetzt, wenn eine andere Session genau die gleiche Zeile auswählt? Oder kann dies nicht passieren, wird dann wenn eine Zeile gesperrt ist diese bei Select-Anweisungen garnicht mehr beachtet, bis diese wieder entsperrt ist? Aus den Fragen ergibt sich für mich auch, wie ich dies in Verbindung mit PHP behandeln muss, wenn zum Beispiel die zweite Session die gleiche Zeile auswählt. Kommt dann ein Fehler zurück und ich muss in einer Schleife arbeiten? arbeitsrechtanwalt.info | primera-division.com | Sportwetten mit Bonus
Mein Seo Blog | sportwettentipps.de Geändert von theHacker (26.04.2011 um 20:52:28 Uhr) Grund: ... |
|
|
|
|
#9 (permalink) |
|
alias Echnaton
|
mit dem SELECT FOR UPDATE setzt Du einen exklusiven LOCK auf die row.
Andere sessions können diese Zeile dann weder lesen noch ändern ( im allgemeinen warten diese sessions dann, bis der Lock wieder aufgehoben ist, nur wenn das zu lange dauert kommt eine Fehlermeldung zurück "Timeout" ). Der Lock, den Du damit etablierst, bleibt bis zum nächsten COMMIT bestehen. Ein COMMIT kann explizit abgesetzt werden, oder implizit durch Beenden des Programms. Vorsicht, wenn Du autocommit verwendest, dann wird nach jedem statement ein automatischer commit abgesetzt und der Lock freigegeben.
"transversalis teleport" sprach der Magier und war fort
|
|
|
|
|
|
#10 (permalink) |
|
Erfahrener Benutzer
|
Super, vielen Dank für die ausführliche Erklärung.
Ich habe es gerade mal in Phpmyadmin versucht dies zu simulieren, indem ich auf eine Tabelle mit 2 Einträgen mehrmals SELECT ... FOR UPDATE aufgerufen habe. Ab dem 3. SELECT ... FOR UPDATE wurden allerdings immernoch Einträge ausgewählt, als wären die nicht gelocked worden. Oder benutzt Phpmyadmin dieses autocommit, das du angesprochen hattest? arbeitsrechtanwalt.info | primera-division.com | Sportwetten mit Bonus
Mein Seo Blog | sportwettentipps.de |
|
|
|
|
#13 (permalink) | |
|
alias Echnaton
|
Zitat:
Ein X-Lock ( exclusive-Lock ) sollte doch auch S-Locks ( Leselocks ) anderer threads verhindern, oder ?
"transversalis teleport" sprach der Magier und war fort
|
|
|
|
|
|
|
#14 (permalink) |
|
return void
|
neija durch den MVCC-Ansatz bzw. die mögliche Implementierung Snapshot Isolation [1] werden nie Leselocks gesetzt, von daher können Reads nicht mit den Schreiblocks unterbunden werden.
Generell ist da das Problem, dass der MVCC-Ansatz viele Grundlagen des ANSI-Isolationsmodells obsolet macht [2], da das Modell Transaktionen auf Basis von Locks beschreibt. [1] http://en.wikipedia.org/wiki/Snapshot_isolation [2] http://research.microsoft.com/pubs/69541/tr-95-51.pdf |
|
|
|
|
|
#15 (permalink) | |||
|
Neuer Benutzer
Reg: 29.04.2011
Beiträge: 3
![]() |
Um nochmal auf die Eingangsfrage zu kommen:
PHP-Code:
|
|||
|
|
|
![]() |
| Gesponsorte Links |
| Anzeige |
| Aktive Benutzer in diesem Thema: 1 (Registrierte Benutzer: 0, Gäste: 1) | |
| Themen-Optionen | |
| Ansicht | |
|
|
Ähnliche Themen
|
||||
| Thema | Autor | Forum | Antworten | Letzter Beitrag |
| Textmarkieren verhindern | Slayer92 | Programmierung | 42 | 07.04.2009 13:16:18 |
| [MySQL] Race Conditions | chrissel | Programmierung | 24 | 12.05.2007 16:47:36 |
| Spam verhindern | eminion | Multimedia & Kommunikation | 16 | 21.02.2007 01:56:01 |
| Rally Race | CroBoy | Lose4Scripts (erledigt) | 28 | 15.01.2007 20:24:49 |