SELECT FOR UPDATE in der Isolationsebene „Wiederholbarer Lesevorgang“ verwenden

Auf dieser Seite wird beschrieben, wie Sie die FOR UPDATE-Klausel in der Isolation für wiederholtes Lesen verwenden.

Der Sperrmechanismus der FOR UPDATE-Klausel unterscheidet sich für die Isolation „Repeatable Read“ und „Serializable“. Anders als bei der serialisierbaren Isolation werden bei der Isolation „Repeatable Read“ (Wiederholbarer Lesevorgang) keine Sperren für die FOR UPDATE-Klausel abgerufen. Weitere Informationen zu Sperren in FOR UPDATE finden Sie unter SELECT FOR UPDATE in serialisierbarer Isolation verwenden.

Informationen zur Verwendung der FOR UPDATE-Klausel finden Sie in den Referenzanleitungen für GoogleSQL und PostgreSQL.FOR UPDATE

Vorteile der FOR UPDATE-Klausel

Wenn eine Transaktion mit der Isolationsebene „Repeatable Read“ ausgeführt wird, werden die von der SELECT-Anweisung abgefragten Daten immer mit dem festgelegten Snapshot-Zeitstempel für die Transaktion zurückgegeben. Wenn die Transaktion dann auf Grundlage der abgefragten Daten Aktualisierungen vornimmt, kann es zu Problemen mit der Richtigkeit kommen, wenn eine gleichzeitige Transaktion auch die abgefragten Daten aktualisiert. Weitere Informationen finden Sie unter Lese-/Schreibkonflikte und Richtigkeit.

Damit die von der SELECT-Anweisung abgefragten Daten beim Commit der Transaktion noch gültig sind, können Sie eine FOR UPDATE-Klausel mit wiederholbarer Leseisolation verwenden. Durch die Verwendung von FOR UPDATE wird die Richtigkeit von Transaktionen trotz Lese-/Schreibkonflikten gewährleistet, bei denen Daten möglicherweise durch eine andere Transaktion zwischen dem Zeitpunkt des Lesens und des Änderns geändert wurden.

Abfragesyntax

In diesem Abschnitt finden Sie Informationen zur Abfragesyntax bei Verwendung der Klausel FOR UPDATE.

Am häufigsten wird sie in einer SELECT-Anweisung auf oberster Ebene verwendet. Beispiel:

SELECT SingerId, SingerInfo
FROM Singers WHERE SingerID = 5
FOR UPDATE;

Die FOR UPDATE-Klausel sorgt dafür, dass die von der SELECT-Anweisung und SingerID = 5 abgefragten Daten weiterhin gültig sind, wenn die Transaktion festgeschrieben wird. So werden Probleme mit der Richtigkeit verhindert, die auftreten könnten, wenn eine gleichzeitige Transaktion die abgefragten Daten aktualisiert.

In WITH-Anweisungen verwenden

Mit der FOR UPDATE-Klausel werden die in der WITH-Anweisung gescannten Bereiche nicht überprüft, wenn Sie FOR UPDATE in der Abfrage auf oberster Ebene der WITH-Anweisung angeben.

In der folgenden Abfrage werden keine gescannten Bereiche validiert, da FOR UPDATE nicht an die CTE-Abfrage (Common Table Expression) weitergegeben wird.

WITH s AS (SELECT SingerId, SingerInfo FROM Singers WHERE SingerID > 5)
SELECT * FROM s
FOR UPDATE;

Wenn die FOR UPDATE-Klausel in der CTE-Abfrage angegeben ist, wird der gescannte Bereich der CTE-Abfrage validiert.

Im folgenden Beispiel werden die Zellen SingerId und SingerInfo für die Zeilen validiert, in denen SingerId > 5.

WITH s AS
  (SELECT SingerId, SingerInfo FROM Singers WHERE SingerId > 5 FOR UPDATE)
SELECT * FROM s;

In Unterabfragen verwenden

Sie können die FOR UPDATE-Klausel in einer Abfrage auf oberster Ebene verwenden, die eine oder mehrere Unterabfragen enthält. Die von der Abfrage der obersten Ebene und in Unterabfragen gescannten Bereiche werden validiert, mit Ausnahme von Ausdrucksunterabfragen.

Mit der folgenden Abfrage werden die Zellen SingerId und SingerInfo für Zeilen validiert, in denen SingerId > 5.

(SELECT SingerId, SingerInfo FROM Singers WHERE SingerId > 5) AS t
FOR UPDATE;

Mit der folgenden Abfrage werden keine Zellen in der Tabelle Albums validiert, da sie sich in einer Unterabfrage für Ausdrücke befindet. Die Zellen SingerId und SingerInfo für die von der Unterabfrage des Ausdrucks zurückgegebenen Zeilen werden validiert.

SELECT SingerId, SingerInfo
FROM Singers
WHERE SingerId = (SELECT SingerId FROM Albums WHERE MarketingBudget > 100000)
FOR UPDATE;

Zum Abfragen von Ansichten verwenden

Sie können die FOR UPDATE-Klausel verwenden, um eine Ansicht abzufragen, wie im folgenden Beispiel gezeigt:

CREATE VIEW SingerBio AS SELECT SingerId, FullName, SingerInfo FROM Singers;

SELECT * FROM SingerBio WHERE SingerId = 5 FOR UPDATE;

Sie können die FOR UPDATE-Klausel beim Definieren einer Ansicht nicht verwenden.

Nicht unterstützte Anwendungsfälle

Die folgenden FOR UPDATE-Anwendungsfälle werden nicht unterstützt:

  • Als gegenseitiger Ausschlussmechanismus für die Ausführung von Code außerhalb von Spanner:Verwenden Sie keine Sperren in Spanner, um den exklusiven Zugriff auf eine Ressource außerhalb von Spanner zu gewährleisten. Transaktionen können von Spanner abgebrochen werden, z. B. wenn eine Transaktion entweder explizit durch Anwendungscode oder implizit durch Clientcode wie den JDBC-Treiber von Spanner wiederholt wird. In diesem Fall wird nur garantiert, dass die Sperren während des tatsächlichen Versuchs bestanden haben.
  • In Kombination mit dem LOCK_SCANNED_RANGES-Hinweis:Sie können die FOR UPDATE-Klausel und den LOCK_SCANNED_RANGES-Hinweis nicht in derselben Abfrage verwenden. Andernfalls gibt Spanner einen Fehler zurück. Weitere Informationen finden Sie unter Vergleich mit dem Hinweis LOCK_SCANNED_RANGES.
  • In Volltextsuchanfragen:Die FOR UPDATE-Klausel kann nicht in Abfragen mit Volltextsuchindexen verwendet werden.
  • In schreibgeschützten Transaktionen:Die FOR UPDATE-Klausel ist nur in Abfragen gültig, die in Lese-/Schreibtransaktionen ausgeführt werden.
  • In DDL-Anweisungen:Die FOR UPDATE-Klausel kann nicht in Abfragen in DDL-Anweisungen verwendet werden, die für die spätere Ausführung gespeichert werden. Sie können beispielsweise die FOR UPDATE-Klausel beim Definieren einer Ansicht nicht verwenden.

Weitere Informationen