|
|
|
|
|
|
|
#12 (permalink) |
|
Erfahrener Benutzer
|
Wenn du dich über Transactions informiert hast, wirst du wissen, wie das funktioniert^^
Transaktionen sind ein in sich geschlossener Prozess. Zum Beispiel: Code:
START TRANSACTION UPDATE `Tabelle` SET `Feld` = NULL COMMIT Da es eine Transaktion ist, kann zwischenzeitlich keine andere Abfrage "reinfummeln". Du brauchst also nicht mit locks zu arbeiten. Die Transaktion hat erst auf deine Datensätze eine Auswirkung, wenn sie komplett abgeschlossen ist, und dann auf alles gleichzeitig. Angenommen folgende Situation: Benutzer A macht ein Update und setzt alle Felder "Geld" auf 0, anschließend mach er ein weiteres Update und setzt alle Felder "Geld" auf 200. Dann fällt ihm auf, das das völliger Schwachsinn war, und macht alles Rückgängig. Benutzer B kommt zwischendrin und liest das Geld aller Benutzer aus. Was kann passieren (nach deiner Problemstellung): Mysql überschreibt alles mit 0, dann mit 200. Mitten drin fragt Benutzer B ab und bekommt ein paar Datensätze die noch auf 0 stehen und ein paar die schon auf 200 stehen (weil er mitten drin abgefragt hat). Benutzer A Code:
START TRANSACTION UPDATE Tabelle SET Geld = 0 UPDATE Tabelle SET Geld = 200 ROLLBACK Code:
SELECT Geld FROM Tabelle Es ist nicht möglich genau dann eine Abfrage zu senden, in der eines der Updates der Transaktion noch nicht fertig ist. Denn die Transaktion hat entweder gar keine Änderung gemacht, oder ist mit allem fertig. Vorher ist die änderung der einzelnen Datensätze sozusagen "nicht bekannt" für andere Abfragen. Sendet ein Benutzer wirklich Millisekunden genau gleichzeitig eine Anfrage muss diese automatisch solange warten, bis mysql mit der Transaktion fertig ist. Erst dann wird Sie ausgeführt und liefert ein Ergebnis zurück. Sollte eigentlich genau das sein was du suchst.
__________________
![]() ![]() |
|
|
|
|
|
#13 (permalink) | |
|
Neuer Benutzer
Registriert seit: 22.01.2010
Beiträge: 25
PHP-Kenntnisse: Fortgeschritten ![]() |
Zitat:
@Frank: Danke für den Schnupperkurs! Nur... nu' hat nikosch doch Recht... ich hätt's noch besser beschreiben müssen. Der Ablauf ist für jeden User: 1) DB Query: SELECT.... Gibt's was zu tun? 2) Wenn ja, ... 2a) PHP: viel php code mit Berechnungen 2b) DB UPDATE: Schreib Ergebnisse zurück in Tabellen Transactions scheitern hier glaube ich, so wie ich das überschau. MySQL scheint wohl einen Serializable Modus für Transactions zu kennen, der aber für PHP nicht funktionieren soll, weil Request / Response basiert. Sind wir wieder beim Semaphor... um den auszulesen und zu setzen wäre eine Transaction aber wohl die Methode der Wahl, so wie es klingt. ![]() Geändert von Samhayne (09.02.2010 um 11:28 Uhr). |
|
|
|
|
|
|
#14 (permalink) | |
|
Neuer Benutzer
Registriert seit: 22.01.2010
Beiträge: 25
PHP-Kenntnisse: Fortgeschritten ![]() |
Oder auch nicht... grad mal bissl getestet.
Das scheint nicht zu stimmen: Zitat:
Gingst aber wahrscheinlich von einem Transactionquery in einem einzigen Block aus, an dessen Ende dann commited wird. So verhält er sich jedoch wie man's von einem so benannten Modus erwarten würde. Beide User bekommen Zugriff.... und sobald der erste user commited.... kriegt auch user 2 die neuen Daten. Davor kriegt er einfach die alten. Ausgabe: Code:
User 1 reads accesslock: open User 1 queries autocommit status: 1 User 1 sets autocommit = false User 1 queries autocommit status: 0 User 1 sets Lock User 1 reads accesslock: locked User 2 queries autocommit status: 1 User 2 reads accesslock: open User 1 committed his changes. User 2 reads accesslock: locked PHP-Code:
Geändert von Samhayne (09.02.2010 um 11:57 Uhr). |
|
|
|
|
|
|
#15 (permalink) |
|
Erfahrener Benutzer
Registriert seit: 26.12.2009
Beiträge: 178
PHP-Kenntnisse: Anfänger ![]() |
ich bin mir nicht sicher, ob das Autocommit mit "SELECT @@autocommit"; deaktiviert wird.
Schau die mal PHP: mysqli::autocommit - Manual PHP-Code:
EDIT: Sorry nehme alles zurück und behaupte das Gegenteil. Vermutlich muss Du auf $db1 und $db2 mit Autocommit FALSE arbeiten. Grüße Thomas Geändert von thomas_w (09.02.2010 um 12:20 Uhr). Grund: EDIT: Korrektur |
|
|
|
|
|
#16 (permalink) | ||
|
Neuer Benutzer
Registriert seit: 22.01.2010
Beiträge: 25
PHP-Kenntnisse: Fortgeschritten ![]() |
Zitat:
Code:
User 1 queries autocommit status: 1 User 1 queries autocommit status: 1 User 1 queries autocommit status: 1 User 1 sets autocommit = false User 1 queries autocommit status: 0 User 1 queries autocommit status: 0 User 1 queries autocommit status: 0 Zitat:
![]() Momentan bin ich wieder zurück bei der Idee, das Lock so zu lösen: UPDATE: wenn 'open' setz meine User ID rein, ansonsten lass es so, wie es ist. PHP-Code:
Anschließend nochmal SELECT Abfrage, ob meine User ID gesetzt ist, wenn ja... fang an zu arbeiten, wenn nicht... 'ne halbe Sekunde Pause und nochmal. Dazu dann eben noch ein 60 Sekunden Timeout, der das Lock mit Gewalt "aufreisst" bzw. noch zusätzlich ein Timestamp in der Tabelle. Hmhm... 'n bißchen frickelig. Aber funktionieren tut's. Ausgabe: Code:
====================================== User 1 tries to access... ====================================== successfully locked by user 1. Doing work... ====================================== User 2 tries to access... ====================================== No access! locked by user 1 PHP-Code:
|
||
|
|
|
|
|
#17 (permalink) |
|
Erfahrener Benutzer
Registriert seit: 26.12.2009
Beiträge: 178
PHP-Kenntnisse: Anfänger ![]() |
Vielleicht testet Du Deine Beispiel noch mit den verschiedenen Isolation Levels
MySQL :: MySQL 5.1 Referenzhandbuch :: 14.2.10.3 InnoDB und TRANSACTION ISOLATION LEVEL Code:
TRANSACTION-Anweisung einstellen, die folgende Syntax hat:
SET [SESSION | GLOBAL] TRANSACTION ISOLATION LEVEL
{READ UNCOMMITTED | READ COMMITTED
| REPEATABLE READ | SERIALIZABLE}
Beachten Sie, dass in den Namen der Ebenen in der --transaction-isolation-Option Bindestriche verwendet werden, aber nicht in der SET TRANSACTION-Anweisung.
Leider habe ich hier keine MySQL am Laufen... kann es also erst heute Abend testen. Grüße Thomas |
|
|
|
|
|
#18 (permalink) | |
|
Neuer Benutzer
Registriert seit: 22.01.2010
Beiträge: 25
PHP-Kenntnisse: Fortgeschritten ![]() |
Hm. *überfordert*
Hab ja nur Autocommit abgeschaltet und danach wieder an. Mit einer Transaction Anweisung an sich könnt ich (glaub ich?) gar nichts anfangen. Wegen Anforderung... Zitat:
an dessen Ende dann ein COMMIT oder ROLLBACK steht. (zumindest bei PHP). Sowatt wie... PHP-Code:
Geändert von Samhayne (09.02.2010 um 13:49 Uhr). |
|
|
|
|
|
|
#19 (permalink) | |
|
moderatives Dielektrikum
Registriert seit: 21.05.2008
Beiträge: 21.228
PHP-Kenntnisse: Fortgeschritten ![]() ![]() ![]() ![]() ![]() ![]() ![]() |
Zitat:
1) wie gehabt. Beachte dabei nachfolgendes 2) Suche Dir eine ID, die Du bearbeiten willst. Setze auf diese ID (DB Update) einen Zeitstempel, der mindestens so weit in der Zukunft liegt, wie die Berechnung dauert. Datensätze mit nicht abgelaufenen Zeitstempeln werden vom Select in 1) ignoriert 3) wie gehabt. 4) wie gehabt. Lösche den Zeitstempel, bei Bedarf.
__________________
-- „Eins ist Fakt: Gescannt wird nackt!“ Privatsphäre 2.0 - Nacktscanner mit Eyetracking. Unser Flugzeug darf kein geschlechtsfreier Raum sein. -- |
|
|
|
|
|
|
#20 (permalink) |
|
Erfahrener Benutzer
Registriert seit: 26.12.2009
Beiträge: 178
PHP-Kenntnisse: Anfänger ![]() |
Noch ein paar Fragen für mein Verständnis:
a) Was soll mit den "wartenden" Usern in der Zeit passieren, solange der "LOCK" User die Daten ändert? => 1) die Skripte der "wartenden" User bleiben hängen und warten bis der LOCK gelöst ist => eventuelles TIMEOUT Problem => 2) die Skripte der "wartenden" User laufen weiter und lesen "alte" Daten b) Wird vom dem "LOCK" User die gesamte Tabelle gesperrt oder nur einzelne Datensätze, -bereiche (von bis Postleitzeit z.B.) c) Wie lange dauert der Update des "LOCK" Users? => 1) wenige (Milli)-Sekunden => 2) mehr als 5 Sekunden d) Wie häufig erfolgt so ein Update des "LOCK" Users? => 1) einmal pro Stunde => 2) sehr häufig => 3) sehr selten Soweit mal ein paar Fragen meinerseits... Ich denke schon, dass es eine Lösung gibt! Grüße Thomas |
|
|
|
|
|
|
|
PHP Code Flüsterer
Registriert seit: 21.08.2005
Beiträge: 4682
PHP-Kenntnisse:
Fortgeschritten
|
|
|
| Themen-Optionen | |
| Thema bewerten | |
|
|
Ähnliche Themen
|
||||
| Thema | Autor | Forum | Antworten | Letzter Beitrag |
| [Erledigt] mysql_insert_id () und LOCK TABLES | Senifor | PHP Einsteiger | 2 | 29.10.2009 15:40 |
| [Erledigt] breadcrumb 2 Tables mit Subcategories | fulltilt | PHP Einsteiger | 6 | 19.09.2009 07:57 |
| Kann LOCK TABLES zu Absturz der MySQL Datenbank führen? | kat_2403 | Datenbanken | 2 | 03.09.2009 15:22 |
| mysqlabfrage mit 2 tables (COUNT?) | mqs | PHP Einsteiger | 6 | 17.06.2009 12:49 |
| Welche Tables muss ich erstellen? | She-Sign.de | Datenbanken | 2 | 12.05.2009 19:54 |
| [Erledigt] LOCK TABLES - Thread statt Table??? | Curanai | Datenbanken | 1 | 04.04.2009 01:33 |
| [Erledigt] Problem bei delete über 2 tables | fulltilt | PHP Einsteiger | 3 | 24.02.2009 22:29 |
| Impossible WHERE noticed after reading const tables | Gumfuzi | Datenbanken | 6 | 03.01.2009 10:53 |
| Extrahieren aus 2 Tables mit einem bekannten Wert | ssm | Datenbanken | 12 | 23.03.2006 20:29 |
| Tables | Schubi | PHP Tipps 2005-2 | 0 | 05.08.2005 15:09 |
| Tables | Schubi | PHP Tipps 2005-2 | 0 | 05.08.2005 15:08 |
| Tables | PHP Tipps 2005-2 | 0 | 05.08.2005 13:39 | |
| LOCK TABLES / LAST_INSERT_ID | AliceD | Datenbanken | 3 | 20.07.2005 13:45 |
| Suche zufalls(bild)script das in tables läuft... | Beitragsarchiv | 0 | 05.07.2005 12:18 | |
| SHOW PROCESSLIST und TEMPORARY TABLES | tapferesschneiderlein | Datenbanken | 2 | 05.03.2005 11:40 |
| Besucher kamen über folgende Suchanfragen bei Google auf diese Seite |
| php sql warten auf insert abgeschlossen, sql table lock user, db2 table lock aufheben, sql lock aufheben, php abbruch mehrfacher insert in db, php status locked, update commit php sperre |