Cette page explique comment utiliser la clause FOR UPDATE
dans l'isolation de lecture répétable.
Le mécanisme de verrouillage de la clause FOR UPDATE
est différent pour l'isolation de lecture reproductible et sérialisable. Contrairement à l'isolation sérialisable, la clause FOR UPDATE
n'acquiert pas de verrous dans l'isolation de lecture répétable. Pour en savoir plus sur les verrous dans FOR UPDATE
, consultez Utiliser SELECT FOR UPDATE dans l'isolation sérialisable.
Pour savoir comment utiliser la clause FOR UPDATE
, consultez les guides de référence GoogleSQL et PostgreSQL pour FOR UPDATE
.
Pourquoi utiliser la clause FOR UPDATE
?
Lorsqu'une transaction s'exécute avec un niveau d'isolation "repeatable read", les données interrogées par l'instruction SELECT
sont toujours renvoyées à l'horodatage de l'instantané établi pour la transaction. Si la transaction effectue ensuite des mises à jour en fonction des données interrogées, des problèmes d'exactitude peuvent survenir si une transaction simultanée met également à jour les données interrogées. Pour en savoir plus, consultez Conflits de lecture/écriture et exactitude.
Pour vous assurer que les données interrogées par l'instruction SELECT
sont toujours valides lorsque la transaction est validée, vous pouvez utiliser une clause FOR UPDATE
avec un niveau d'isolation de lecture "repeatable read". L'utilisation de FOR UPDATE
garantit la correction des transactions malgré les conflits de lecture/écriture, où les données peuvent avoir été modifiées par une autre transaction entre le moment où elles ont été lues et celui où elles ont été modifiées.
Syntaxe des requêtes
Cette section fournit des conseils sur la syntaxe des requêtes lorsque vous utilisez la clause FOR UPDATE
.
L'utilisation la plus courante se fait dans une instruction SELECT
de premier niveau. Exemple :
SELECT SingerId, SingerInfo
FROM Singers WHERE SingerID = 5
FOR UPDATE;
La clause FOR UPDATE
garantit que les données interrogées par l'instruction SELECT
et SingerID = 5
sont toujours valides lorsque la transaction est validée. Cela permet d'éviter les problèmes d'exactitude qui pourraient survenir si une transaction simultanée met à jour les données interrogées.
Utilisation dans les instructions WITH
La clause FOR UPDATE
ne vérifie pas les plages analysées dans l'instruction WITH
lorsque vous spécifiez FOR UPDATE
dans la requête de niveau extérieur de l'instruction WITH
.
Dans la requête suivante, aucune plage analysée n'est validée, car FOR UPDATE
n'est pas propagé à la requête d'expression de table commune (CTE).
WITH s AS (SELECT SingerId, SingerInfo FROM Singers WHERE SingerID > 5)
SELECT * FROM s
FOR UPDATE;
Si la clause FOR UPDATE
est spécifiée dans la requête CTE, la plage analysée de la requête CTE est validée.
Dans l'exemple suivant, les cellules SingerId
et SingerInfo
des lignes où SingerId > 5
sont validées.
WITH s AS
(SELECT SingerId, SingerInfo FROM Singers WHERE SingerId > 5 FOR UPDATE)
SELECT * FROM s;
Utilisation dans les sous-requêtes
Vous pouvez utiliser la clause FOR UPDATE
dans une requête de niveau externe comportant une ou plusieurs sous-requêtes. Les plages analysées par la requête de niveau supérieur et dans les sous-requêtes sont validées, sauf dans les sous-requêtes d'expression.
La requête suivante valide les cellules SingerId
et SingerInfo
pour les lignes où SingerId > 5.
.
(SELECT SingerId, SingerInfo FROM Singers WHERE SingerId > 5) AS t
FOR UPDATE;
La requête suivante ne valide aucune cellule de la table Albums
, car elle se trouve dans une sous-requête d'expression. Les cellules SingerId
et SingerInfo
des lignes renvoyées par la sous-requête d'expression sont validées.
SELECT SingerId, SingerInfo
FROM Singers
WHERE SingerId = (SELECT SingerId FROM Albums WHERE MarketingBudget > 100000)
FOR UPDATE;
Utiliser pour interroger les vues
Vous pouvez utiliser la clause FOR UPDATE
pour interroger une vue, comme illustré dans l'exemple suivant :
CREATE VIEW SingerBio AS SELECT SingerId, FullName, SingerInfo FROM Singers;
SELECT * FROM SingerBio WHERE SingerId = 5 FOR UPDATE;
Vous ne pouvez pas utiliser la clause FOR UPDATE
lors de la définition d'une vue.
Cas d'utilisation non compatibles
Les cas d'utilisation suivants de FOR UPDATE
ne sont pas pris en charge :
- En tant que mécanisme d'exclusion mutuelle pour l'exécution de code en dehors de Spanner : n'utilisez pas le verrouillage dans Spanner pour garantir un accès exclusif à une ressource en dehors de Spanner. Les transactions peuvent être annulées par Spanner, par exemple si une transaction est relancée, que ce soit explicitement par un code d'application ou implicitement par un code client, tel que le pilote JDBC Spanner. La seule garantie est le maintien des verrous pendant la tentative réellement effectuée.
- En combinaison avec l'indication
LOCK_SCANNED_RANGES
: vous ne pouvez pas utiliser à la fois la clauseFOR UPDATE
et l'indicationLOCK_SCANNED_RANGES
dans la même requête. Dans le cas contraire, Spanner renvoie une erreur. Pour en savoir plus, consultez Comparaison avec l'indiceLOCK_SCANNED_RANGES
. - Dans les requêtes de recherche en texte intégral : vous ne pouvez pas utiliser la clause
FOR UPDATE
dans les requêtes utilisant des index de recherche en texte intégral. - Dans les transactions en lecture seule : la clause
FOR UPDATE
n'est valide que dans les requêtes exécutées dans des transactions en lecture-écriture. - Dans les instructions LDD : vous ne pouvez pas utiliser la clause
FOR UPDATE
dans les requêtes des instructions LDD, qui sont stockées pour être exécutées ultérieurement. Par exemple, vous ne pouvez pas utiliser la clauseFOR UPDATE
lors de la définition d'une vue.
Étape suivante
- Découvrez comment utiliser la clause
FOR UPDATE
dans GoogleSQL et PostgreSQL. - Découvrez comment utiliser SELECT FOR UPDATE dans l'isolation sérialisable.
- En savoir plus sur l'indice
LOCK_SCANNED_RANGES
- En savoir plus sur le verrouillage dans Spanner