Wie wird eine MySQL-Zeile absichtlich gesperrt, so dass selbst SELECT einen Fehler zurückgibt?

8

Ich versuche, die MySQL-Zeilensperre zu verwenden, um einen MuteEx in einer Zeile zu emulieren. Nehmen wir an, dass meine Tabelle zwei Spalten, eine ID und ein Textfeld sowie drei Einträge (1, a) (2, b) und (3, c) enthält. SELECT * FROM Tabelle; würde diese Ergebnisse zurückgeben. Ich kann eine bestimmte Zeile auf die normale Weise sperren.

%Vor%

Wenn ich jedoch von einer zweiten Verbindung aus SELECT * aus der Tabelle wählen würde. Es würde alle 3 Ergebnisse zurückgeben. Gibt es eine Möglichkeit zum Sperren auf Zeilenebene, um zu verhindern, dass SELECT eine gesperrte Zeile sieht / verwendet? Im Grunde versuche ich zu verhindern, dass irgendjemand die gerade verwendete / manipulierte Zeile benutzt, oder sogar die Zeile als ihre Daten anzusehen (da sie benutzt / manipuliert wird), kann nicht vertrauenswürdig sein, um zum Zeitpunkt einer AUSWAHL genau zu sein .

    
bahhumbug 12.01.2010, 18:10
quelle

4 Antworten

5

Wenn Sie die Transaktionsisolationsstufe auf SERIALIZABLE , InnoDB wil implicity, setzen Sie LOCK IN SHARE MODE auf alle SELECT -Anweisungen.

Dieser Modus steht im Konflikt mit den Sperren, die von SELECT FOR UPDATE und von SELECT s gesetzt wurden.

Beachten Sie jedoch, dass InnoDB möglicherweise mehr Zeilen sperrt als die Bedingung WHERE erfüllt. Dies liegt daran, dass alle gescannten Zeilen gesperrt werden, nicht nur die übereinstimmenden .

Angenommen, Sie haben einen Index für col1 und diese Abfrage:

%Vor%

verwendet diesen Index.

Dadurch werden alle Datensätze mit col1 = 1 gesperrt, sogar mit col2 <> 2

    
Quassnoi 12.01.2010 18:30
quelle
5

Sie benötigen ein LOCK IN SHARE MODE . Die Verwendung mit SELECT garantiert, dass niemand sonst Zeilen mit FOR UPDATE schließt.

z.B.

Client A tut SELECT * FROM table WHERE type=2 FOR UPDATE

Client B tut SELECT * FROM table LOCK IN SHARE MODE und hängt hier

Client A schreibt / INSERTs / UPDATEs etwas und dann ein COMMIT

Client B deaktiviert nun die Verarbeitung und setzt die Verarbeitung fort

    
servermanfail 22.02.2011 10:30
quelle
2

Tatsächlich können die Zeilendaten sogar während der Bearbeitung vertrauenswürdig sein.

Wenn Sie eine Transaktion von einer Verbindung aus starten, sehen andere Verbindungen keine Ihrer Änderungen, bis Sie die Transaktion festgeschrieben haben.

    
Timo Stamm 12.01.2010 18:45
quelle
0

Ich weiß nicht, ob es einen nativen, sperrenden Mechanismus dafür gibt, aber mein erster Grund wäre, der Tabelle eine Statusspalte zu geben (zB locked ) und diese auf 1 zu setzen, wenn ich die Sperre sperre Reihe. Ein select sensitive würde dann immer eine WHERE locked != '1' Bedingung zu jeder Abfrage hinzufügen.

Nebenbei bemerkt, ich weiß nicht, was Sie tun, aber ist das nicht eine Aufgabe, die ein oder zwei Level über der Datenbank-Engine durchgeführt werden sollte?

    
Pekka 웃 12.01.2010 18:15
quelle

Tags und Links