Nesta página, descrevemos como usar a cláusula FOR UPDATE
no
isolamento de leitura repetida.
O mecanismo de bloqueio da cláusula FOR UPDATE
é diferente para leitura
repetível e isolamento serializável. Ao contrário do isolamento serializável, a cláusula FOR UPDATE
não adquire bloqueios no isolamento de leitura repetível. Para mais
informações sobre bloqueios em FOR UPDATE
, consulte Usar SELECT FOR UPDATE em
isolamento serializável.
Para saber como usar a cláusula FOR UPDATE
, consulte os guias de referência do GoogleSQL e do PostgreSQL
FOR UPDATE
.
Por que usar a cláusula FOR UPDATE
Quando uma transação é executada com isolamento de leitura repetível, os dados consultados
pela instrução SELECT
sempre são retornados no carimbo de data/hora do snapshot
estabelecido para a transação. Se a transação fizer atualizações com base nos dados consultados, poderá haver problemas de correção se uma transação simultânea também atualizar os dados consultados. Para mais informações, consulte
Conflitos de leitura e gravação e correção.
Para garantir que os dados consultados pela instrução SELECT
ainda sejam válidos quando a transação for confirmada, use uma cláusula FOR UPDATE
com isolamento de leitura repetível. O uso de FOR UPDATE
garante a correção da transação apesar de conflitos de leitura/gravação em que os dados podem ter sido modificados por outra transação entre o momento em que foram lidos e modificados.
Sintaxe das consultas
Esta seção fornece orientações sobre a sintaxe de consulta ao usar a cláusula FOR UPDATE
.
O uso mais comum é em uma instrução SELECT
de nível superior. Exemplo:
SELECT SingerId, SingerInfo
FROM Singers WHERE SingerID = 5
FOR UPDATE;
A cláusula FOR UPDATE
garante que os dados consultados pela instrução SELECT
e SingerID = 5
ainda sejam válidos quando a transação for confirmada, evitando problemas de correção que podem surgir se uma transação simultânea atualizar os dados consultados.
Uso em instruções WITH
A cláusula FOR UPDATE
não verifica os intervalos verificados na instrução WITH
quando você especifica FOR UPDATE
na consulta de nível externo da instrução WITH
.
Na consulta a seguir, nenhum intervalo verificado é validado porque
o FOR UPDATE
não é propagado para a consulta de expressões de tabela comuns (CTE).
WITH s AS (SELECT SingerId, SingerInfo FROM Singers WHERE SingerID > 5)
SELECT * FROM s
FOR UPDATE;
Se a cláusula FOR UPDATE
for especificada na consulta de CTE, o intervalo verificado
da consulta de CTE será validado.
No exemplo a seguir, as células SingerId
e SingerInfo
das linhas em que SingerId > 5
são validadas.
WITH s AS
(SELECT SingerId, SingerInfo FROM Singers WHERE SingerId > 5 FOR UPDATE)
SELECT * FROM s;
Uso em subconsultas
É possível usar a cláusula FOR UPDATE
em uma consulta de nível externo que tenha uma ou mais subconsultas. Os intervalos verificados pela consulta de nível superior e nas subconsultas são validados, exceto em subconsultas de expressão.
A consulta a seguir valida as células SingerId
e SingerInfo
para linhas
em que SingerId > 5.
(SELECT SingerId, SingerInfo FROM Singers WHERE SingerId > 5) AS t
FOR UPDATE;
A consulta a seguir não valida nenhuma célula na tabela Albums
porque
está em uma subconsulta de expressão. As células SingerId
e SingerInfo
das linhas retornadas pela subconsulta de expressão são validadas.
SELECT SingerId, SingerInfo
FROM Singers
WHERE SingerId = (SELECT SingerId FROM Albums WHERE MarketingBudget > 100000)
FOR UPDATE;
Usado para consultar visualizações
Você pode usar a cláusula FOR UPDATE
para consultar uma visualização, conforme mostrado no exemplo a seguir:
CREATE VIEW SingerBio AS SELECT SingerId, FullName, SingerInfo FROM Singers;
SELECT * FROM SingerBio WHERE SingerId = 5 FOR UPDATE;
Não é possível usar a cláusula FOR UPDATE
ao definir uma visualização.
Casos de uso não aceitos
Os seguintes casos de uso do FOR UPDATE
não são compatíveis:
- Como um mecanismo de exclusão mútua para execução de código fora do Spanner:não use o bloqueio no Spanner para garantir acesso exclusivo a um recurso fora dele. As transações podem ser canceladas pelo Spanner, por exemplo, se uma transação for repetida, seja explicitamente pelo código do aplicativo ou implicitamente pelo código do cliente, como o driver JDBC do Spanner, só é garantido que os bloqueios sejam mantidos durante a tentativa que foi executada.
- Em combinação com a dica
LOCK_SCANNED_RANGES
:não é possível usar a cláusulaFOR UPDATE
e a dicaLOCK_SCANNED_RANGES
na mesma consulta. Caso contrário, o Spanner vai retornar um erro. Para mais informações, consulte Comparação com a dicaLOCK_SCANNED_RANGES
. - Em consultas de pesquisa de texto completo:não é possível usar a cláusula
FOR UPDATE
em consultas que usam índices de pesquisa de texto completo. - Em transações somente leitura:a cláusula
FOR UPDATE
só é válida em consultas executadas em transações de leitura e gravação. - Em instruções DDL:não é possível usar a cláusula
FOR UPDATE
em consultas dentro de instruções DDL, que são armazenadas para execução posterior. Por exemplo, não é possível usar a cláusulaFOR UPDATE
ao definir uma visualização.
A seguir
- Saiba como usar a cláusula
FOR UPDATE
no GoogleSQL e no PostgreSQL. - Saiba como usar SELECT FOR UPDATE no isolamento serializável.
- Saiba mais sobre a dica
LOCK_SCANNED_RANGES
. - Saiba mais sobre o bloqueio no Spanner.