Verständnis Problem: lock oder etwas vergleichbares
-
Hallo,
erst mal die Ausgangssituation, ich habe eine php Anwendung die von ein paar Usern genutzt wird. Bei jedem Aufruf der Seite werden die ältesten 10 Zeilen aus einer Tabelle Selektiert. Die Selektierten Daten werden dann zum verarbeiten von Aktionen genutz. Jede Zeile dieser Tabelle stellt eine Aktion da, die Zeile wird nach dem Verarbeiten gelöscht.Jetzt zum Problem:
wenn 2 (oder auch mehr) User im exakt gleichen Moment die Seite aufrufen können die Aktionen gleichzeitig Selektiert werden, somit würden die Aktionen mehr als einmal verarbeitet werden, was absolut inakzeptabel ist.Jetzt meine Frage:
Wie kann ich die Zeilen die ich Selektiere so lange für SELECT Anweisungen sperren bis ich sie lösche?http://dev.mysql.com/doc/refman/5.1/de/innodb-lock-modes.html
Ich denke das lock mode´s das richtige sind jedoch versteh ich nicht wie ich sie anwenden kann in meinen Tests kommt der gewünschte Effekt nicht zustande:
SELECT * FROM test ORDER BY test1 DESC LOCK IN EXKLUSIV MODE LIMIT 0, 10 -- Fehlermeldung SELECT * FROM test ORDER BY test1 DESC LOCK IN SHARED MODE LIMIT 0, 10 -- Kein Fehler aber auch kein Augenscheinlicher Effekt
-
Die Sperren bei DBMS sind Konzepte die vonm DBMS implementiert werden. Meines Erachtens nach kannst du das nicht explizit beeinflussen, d.h. emanuell Locks verteilen oder nicht.
Was du machen kannst ist die Anfrage als "Transaktion" durchzuführen.
tt
-
Ein X-Lock ist das Richtige. Damit hat der andere User keinerlei Zugriff mehr auf die Tabelle.
Eine Fehlermeldung? Welche denn? Kann es denn nicht einfach sein, dass die andere Transaktion bereits über ein SELECT automatisch einen S-Lock auf die Zeilen gelegt hat?
Anderes Problem auf das du mit dem X-Lock aufpassen musst: Deadlocks.
Wenn du von Locks in Datnebanken überhaupt keine Ahnung hast, mach deinem Arbeitgeber den Gefallen und gib das als Teilauftrag einem kompetenten Fachmann. Wenn du hier Mist baust kann das böse Auswirkungen haben.
MfG SideWinder
-
lol für die arbeit brauch ich das nicht^^
kannst du mir da ein tutorial geben oder mir ein beispiel zeigen?
-
Sind deine tabellen überhaupt innodb oder myisam?
wenn myisam dann gibt es eine Sperre auf Tabellenebene was ich aber auch nicht so gut finde. Überdenke lieber dein Design des Programmes.
Sperren sind immer schlecht.
-
wie wäre es, wenn du der tabelle noch ein spalte "owner" spendierst, die ist immer null, außer, wenn sich die einer geschnappt hat.
beim aufruf machst du dann folgendes:
update <table> set owner = <eindeutige_ownerid> where <table_key> in (select <table_key> from <table> where owner is null limit 0,10);und danach halt einen
select * from <table> where <owner> = <eindeutige_ownerid>;die updates sollten ja serialisiert ablaufen...
wenn man das update noch mit einem zeitstempel versieht kann man nicht bearbeitete einträge nach eine bestimmten zeit auch wieder freigeben...ich mache das so ähnlich für eine verteile simulation, die worker markieren sich so ihre jobs und holen die danach raus...
so kümmert sich das dbms darum, das die jobs immer nur einmal abgearbeitet werden...
-
Unix-Tom schrieb:
Sind deine tabellen überhaupt innodb oder myisam?
wenn myisam dann gibt es eine Sperre auf Tabellenebene was ich aber auch nicht so gut finde. Überdenke lieber dein Design des Programmes.
Sperren sind immer schlecht.Mein Test war mit innoDB.
jenz schrieb:
wie wäre es, wenn du der tabelle noch ein spalte "owner" spendierst, die ist immer null, außer, wenn sich die einer geschnappt hat.
beim aufruf machst du dann folgendes:
update <table> set owner = <eindeutige_ownerid> where <table_key> in (select <table_key> from <table> where owner is null limit 0,10);und danach halt einen
select * from <table> where <owner> = <eindeutige_ownerid>;die updates sollten ja serialisiert ablaufen...
wenn man das update noch mit einem zeitstempel versieht kann man nicht bearbeitete einträge nach eine bestimmten zeit auch wieder freigeben...ich mache das so ähnlich für eine verteile simulation, die worker markieren sich so ihre jobs und holen die danach raus...
so kümmert sich das dbms darum, das die jobs immer nur einmal abgearbeitet werden...Diese Idee hatte ich auch und wollte fragen ob das auch eine alternative war - du bist mir zuvor gekommen
- zumal überall wo etwas über locks stand empfohlen wurde sie zu vermeiden^^.
wenn du mir das empfiehlst werde ich das gerne so machen
vielen Dank dafür