Questa pagina descrive come utilizzare la clausola FOR UPDATE
nell'isolamento di lettura ripetibile.
Il meccanismo di blocco della clausola FOR UPDATE
è diverso per l'isolamento
serializzabile e di lettura ripetibile. A differenza dell'isolamento serializzabile, la
clausola FOR UPDATE
non acquisisce blocchi nell'isolamento di lettura ripetibile. Per ulteriori
informazioni sui blocchi in FOR UPDATE
, consulta Utilizzare SELECT FOR UPDATE nell'isolamento
serializzabile.
Per scoprire come utilizzare la clausola FOR UPDATE
, consulta le guide di riferimento di GoogleSQL e PostgreSQL
FOR UPDATE
.
Perché utilizzare la clausola FOR UPDATE
Quando una transazione viene eseguita con l'isolamento di lettura ripetibile, i dati interrogati
dall'istruzione SELECT
vengono sempre restituiti al timestamp dello snapshot stabilito
per la transazione. Se la transazione esegue aggiornamenti in base ai dati sottoposti a query, potrebbero verificarsi problemi di correttezza se anche una transazione simultanea aggiorna i dati sottoposti a query. Per ulteriori informazioni, vedi
Conflitti di lettura/scrittura e correttezza.
Per garantire che i dati interrogati dall'istruzione SELECT
siano ancora validi quando viene eseguito il commit della transazione, puoi utilizzare una clausola FOR UPDATE
con isolamento di lettura ripetibile. L'utilizzo di FOR UPDATE
garantisce la correttezza della transazione nonostante
i conflitti di lettura/scrittura in cui i dati potrebbero essere stati modificati da un'altra transazione
tra il momento della lettura e quello della modifica.
Sintassi delle query
Questa sezione fornisce indicazioni sulla sintassi delle query quando utilizzi la clausola FOR UPDATE
.
L'utilizzo più comune è in un'istruzione SELECT
di primo livello. Ad esempio:
SELECT SingerId, SingerInfo
FROM Singers WHERE SingerID = 5
FOR UPDATE;
La clausola FOR UPDATE
garantisce che i dati interrogati dall'istruzione SELECT
e da SingerID = 5
siano ancora validi quando viene eseguito il commit della transazione, evitando problemi di correttezza che potrebbero verificarsi se una transazione simultanea aggiorna i dati interrogati.
Utilizzo nelle istruzioni WITH
La clausola FOR UPDATE
non verifica gli intervalli analizzati all'interno dell'istruzione WITH
quando specifichi FOR UPDATE
nella query di livello esterno dell'istruzione WITH
.
Nella seguente query, nessun intervallo scansionato viene convalidato perché
FOR UPDATE
non viene propagato alla query dell'espressione della tabella comune (CTE).
WITH s AS (SELECT SingerId, SingerInfo FROM Singers WHERE SingerID > 5)
SELECT * FROM s
FOR UPDATE;
Se la clausola FOR UPDATE
è specificata nella query CTE, viene convalidato l'intervallo scansionato della query CTE.
Nell'esempio seguente, le celle SingerId
e SingerInfo
per le righe in cui SingerId > 5
vengono convalidate.
WITH s AS
(SELECT SingerId, SingerInfo FROM Singers WHERE SingerId > 5 FOR UPDATE)
SELECT * FROM s;
Utilizzo nelle sottoquery
Puoi utilizzare la clausola FOR UPDATE
in una query di livello esterno che contiene una o più
subquery. Gli intervalli analizzati dalla query di primo livello e all'interno delle subquery vengono convalidati, tranne nelle subquery di espressione.
La seguente query convalida le celle SingerId
e SingerInfo
per le righe
in cui SingerId > 5.
(SELECT SingerId, SingerInfo FROM Singers WHERE SingerId > 5) AS t
FOR UPDATE;
La seguente query non convalida alcuna cella nella tabella Albums
perché
si trova all'interno di una sottoquery di espressione. Le celle SingerId
e SingerInfo
per
le righe restituite dalla sottoquery dell'espressione vengono convalidate.
SELECT SingerId, SingerInfo
FROM Singers
WHERE SingerId = (SELECT SingerId FROM Albums WHERE MarketingBudget > 100000)
FOR UPDATE;
Utilizzare per eseguire query sulle visualizzazioni
Puoi utilizzare la clausola FOR UPDATE
per eseguire una query su una vista come mostrato nell'esempio seguente:
CREATE VIEW SingerBio AS SELECT SingerId, FullName, SingerInfo FROM Singers;
SELECT * FROM SingerBio WHERE SingerId = 5 FOR UPDATE;
Non puoi utilizzare la clausola FOR UPDATE
quando definisci una vista.
Casi d'uso non supportati
I seguenti casi d'uso di FOR UPDATE
non sono supportati:
- Come meccanismo di esclusione reciproca per l'esecuzione di codice al di fuori di Spanner: non utilizzare il blocco in Spanner per garantire l'accesso esclusivo a una risorsa al di fuori di Spanner. Le transazioni potrebbero essere interrotte da Spanner, ad esempio, se una transazione viene ritentata, in modo esplicito dal codice dell'applicazione o implicito dal codice client, ad esempio il driver JDBC di Spanner, è garantito che i blocchi vengano mantenuti durante il tentativo di commit.
- In combinazione con il suggerimento
LOCK_SCANNED_RANGES
: Non puoi utilizzare sia la clausolaFOR UPDATE
sia il suggerimentoLOCK_SCANNED_RANGES
nella stessa query, altrimenti Spanner restituisce un errore. Per ulteriori informazioni, consulta Confronto con il suggerimentoLOCK_SCANNED_RANGES
. - Nelle query di ricerca full-text:non puoi utilizzare la clausola
FOR UPDATE
nelle query che utilizzano indici di ricerca full-text. - Nelle transazioni di sola lettura:la clausola
FOR UPDATE
è valida solo nelle query eseguite all'interno delle transazioni di lettura/scrittura. - All'interno delle istruzioni DDL:non puoi utilizzare la clausola
FOR UPDATE
nelle query all'interno delle istruzioni DDL, che vengono archiviate per l'esecuzione successiva. Ad esempio, non puoi utilizzare la clausolaFOR UPDATE
quando definisci una vista.
Passaggi successivi
- Scopri come utilizzare la clausola
FOR UPDATE
in GoogleSQL e PostgreSQL. - Scopri come utilizzare SELECT FOR UPDATE nell'isolamento serializzabile.
- Scopri di più sul suggerimento
LOCK_SCANNED_RANGES
. - Scopri di più sul blocco in Spanner.