LOCK

Name

LOCK -- sperrt eine Tabelle

Synopsis

LOCK [ TABLE ] name [, ...] [ IN sperrmodus MODE ]

wobei sperrmodus Folgendes sein kann:

    ACCESS SHARE | ROW SHARE | ROW EXCLUSIVE | SHARE UPDATE EXCLUSIVE
    | SHARE | SHARE ROW EXCLUSIVE | EXCLUSIVE | ACCESS EXCLUSIVE

Beschreibung

LOCK TABLE setzt eine Sperre auf Tabellenebene und wartet wenn nötig, bis Sperren, die in Konflikt zu dieser stehen, aufgegeben werden. Wenn eine Sperre gesetzt wurde, dann bleibt sie bis zum Ende der aktuellen Transaktion erhalten. (Es gibt keinen Befehl UNLOCK TABLE; Sperren werden immer am Transaktionsende aufgegeben.)

PostgreSQL setzt immer die am wenigsten restriktive Sperre, wenn ein Befehl eine verwendete Tabelle automatisch sperrt. LOCK TABLE ist für Fälle gedacht, in denen Sie restriktivere Sperren benötigen. Nehmen wir an, Sie wollen eine Transaktion im Isolationsgrad Read Committed ausführen und müssen sicherstellen, dass die Daten in einer Tabelle während der Transaktion stabil bleiben. Dazu könnten Sie für die Tabelle eine Sperre im Modus SHARE setzen, bevor Sie die Anfragen starten. Dadurch werden gleichzeitige Datenänderungen verhindert und den folgenden Lesevorgängen eine stabile Sicht auf die geschriebenen Daten ermöglicht, weil die Sperre im Modus SHARE mit der Sperre im Modus ROW EXCLUSIVE, welche von Lesevorgängen angefordert wird, in Konflikt steht und Ihr Befehl LOCK TABLE name IN SHARE MODE wartet, bis alle Halter einer Sperre des Modus ROW EXCLUSIVE abschließen oder zurückrollen. Wenn Sie also die Sperre erst einmal gesetzt haben, dann gibt es keine Transaktionen mehr, die eventuell noch zu schreibende Daten ausstehen haben; des Weiteren müssen neue Schreibvorgänge warten, bis die Sperre aufgegeben wird.

Wenn Sie eine ähnliche Wirkung erzielen wollen und die Transaktion im Isolationsgrad Serializable ausführen, dann müssen Sie den Befehl LOCK TABLE vor allen Datenmodifikationsbefehlen ausführen. Die Datensicht einer serialisierbaren Transaktion wird eingefroren, wenn der erste Datenmodifikationsbefehl ausgeführt wird. Ein später ausgeführtes LOCK TABLE verhindert trotzdem gleichzeitige Schreibvorgänge, aber es kann nicht versichern, dass die Daten, die von der Transaktion gelesen werden, auch die letzten gültigen Daten sind.

Wenn eine Transaktion dieser Art die Daten in der Tabelle ändert möchte, dann sollte sie statt dem Modus SHARE den Modus SHARE ROW EXCLUSIVE verwenden. Damit erreicht man, dass nur eine Transaktion dieser Art zur gleichen Zeit laufen kann. Ohne diese Maßnahme ist eine Verklemmung möglich: Zwei Transaktionen könnten beide eine Sperre im Modus SHARE setzen und dann wäre es beiden nicht möglich eine Sperre im Modus ROW EXCLUSIVE zu erlangen, die sie für den Schreibvorgang benötigen. (Beachten Sie, dass die eigenen Sperren einer Transaktion niemals mit sich in Konflikt stehen. Also kann eine Transaktion eine ROW EXCLUSIVE-Sperre setzen, wenn Sie schon eine SHARE-Sperre hält -- aber nicht, wenn eine andere Transaktion eine SHARE-Sperre hält.) Um Verklemmungen zu vermeiden, sollte Sie dafür sorgen, dass alle Transaktionen, die Sperren für die selben Objekte in der selben Reihenfolge anfordern, und dass, wenn mehrere Sperren für ein Objekt im Spiel sind, Transaktionen immer die Sperre im restriktivsten Modus zuerst setzen.

Weitere Informationen über die Sperrmodi und die Verwendung von Sperren finden Sie in Abschnitt 12.3.

Parameter

name

Der Name der zu sperrenden Tabelle (möglicherweise mit Schemaqualifikation).

Ein Befehl der Form LOCK a, b; hat die gleiche Auswirkung wie LOCK a; LOCK b;. Die Tabellen werden einzeln in der Reihenfolge, wie sie im LOCK-Befehl angegeben wurden, gesperrt.

sperrmodus

Der Sperrmodus gibt an, mit welchen Sperren diese Sperre in Konflikt steht. Die Sperrmodi sind in Abschnitt 12.3 beschrieben.

Wenn kein Sperrmodus angegeben ist, dann wird ACCESS EXCLUSIVE, der restriktivste Sperrmodus, verwendet.

Meldungen

LOCK TABLE

Meldung, wenn die Sperre erfolgreich gesetzt wurde.

Hinweise

Für LOCK ... IN ACCESS SHARE MODE benötigt man das Privileg SELECT für die Zieltabelle. Für alle anderen Formen von LOCK benötigt man das Privileg UPDATE oder DELETE.

LOCK ist nur in einem Transaktionsblock (BEGIN/COMMIT-Paar) sinnvoll, weil die Sperre am Ende einer Transaktion aufgegeben wird. Wenn LOCK außerhalb eines Transaktionsblock aufgerufen wird, dann bildet es selbst eine Transaktion, also würde die Sperre sofort nach Ende des Befehls wieder aufgegeben werden.

LOCK TABLE setzt nur Sperren auf Tabellenebene. Die Modusnamen, die ROW (Zeile) enthalten, sind unzutreffend. Diese Modusnamen sollten generell als Hinweis auf die Absicht des Benutzers verstanden werden, in der gesperrten Tabelle Zeilensperren zu setzen. Außerdem ist der Modus ROW EXCLUSIVE keine exklusive sondern eine geteilte Sperre. Merken Sie sich, dass die Sperrmodi soweit es LOCK TABLE betrifft alle identische Bedeutungen haben und sich nur dadurch unterscheiden, mit welchen Sperrmodi sie in Konflikt stehen.

Beispiele

Dieses Beispiel verwendet eine Sperre im Modus SHARE für die Primärschlüsseltabelle, um die Fremdschlüsseltabelle sicher aktualisieren zu können:

BEGIN WORK;
LOCK TABLE filme IN SHARE MODE;
SELECT id FROM filme 
    WHERE name = 'Star Wars: Episode I - Die dunkle Bedrohung';
-- Hier ROLLBACK, wenn kein Datensatz zurückgegeben wurde
INSERT INTO filme_benutzerkommentare VALUES 
    (_id_, 'Super! Habe lange genug darauf gewartet!');
COMMIT WORK;

Dieses Beispiel setzt eine Sperre im Modus SHARE ROW EXCLUSIVE für die Primärschlüsseltabelle, während eine Löschoperation durchgeführt wird:

BEGIN WORK;
LOCK TABLE filme IN SHARE ROW EXCLUSIVE MODE;
DELETE FROM filme_benutzerkommentare WHERE id IN
    (SELECT id FROM filme WHERE bewertung < 5);
DELETE FROM filme WHERE bewertung < 5;
COMMIT WORK;

Kompatibilität

Im SQL-Standard gibt es keinen Befehl LOCK TABLE. Der SQL-Standard bietet nur SET TRANSACTION um die Konsistenz im Mehrbenutzerbetrieb zu kontrollieren. PostgreSQL bietet diese Funktionalität ebenfalls; siehe SET TRANSACTION.

Außer den Sperrmodi ACCESS SHARE, ACCESS EXCLUSIVE und SHARE UPDATE EXCLUSIVE sind die PostgreSQL-Sperrmodi und die Syntax des Befehls LOCK TABLE mit Oracle kompatibel.