Use SELECT FOR UPDATE no isolamento de leitura repetível

Esta página descreve como usar a cláusula FOR UPDATE em isolamento de leitura repetível.

O mecanismo de bloqueio da cláusula FOR UPDATE é diferente para a leitura repetível e o 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 Use SELECT FOR UPDATE in serializable isolation.

Para saber como usar a cláusula FOR UPDATE, consulte os guias de referência do GoogleSQL e do PostgreSQL FOR UPDATE.

Por que motivo deve usar a cláusula FOR UPDATE

Quando uma transação é executada com isolamento de leitura repetível, os dados consultados pela declaração SELECT são sempre devolvidos na data/hora do instantâneo estabelecida para a transação. Se a transação fizer atualizações com base nos dados consultados, podem ocorrer problemas de correção se uma transação simultânea também atualizar os dados consultados. Para mais informações, consulte o artigo Conflitos de leitura/escrita e correção.

Para garantir que os dados consultados pela declaração SELECT ainda são válidos quando a transação é confirmada, pode usar uma cláusula FOR UPDATE com isolamento de leitura repetível. A utilização de FOR UPDATE garante a correção das transações apesar dos conflitos de leitura/escrita em que os dados podem ter sido modificados por outra transação entre o momento em que foram lidos e modificados.

Sintaxe de consulta

Esta secção fornece orientações sobre a sintaxe de consulta quando usa a cláusula FOR UPDATE.

A utilização mais comum é numa declaração SELECT de nível superior. Por exemplo:

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

A cláusula FOR UPDATE garante que os dados consultados pela declaração SELECT e SingerID = 5 continuam válidos quando a transação é confirmada, o que evita problemas de correção que possam surgir se uma transação simultânea atualizar os dados consultados.

Use em declarações WITH

A cláusula FOR UPDATE não valida os intervalos analisados na declaração WITH quando especifica FOR UPDATE na consulta de nível exterior da declaração WITH.

Na consulta seguinte, não são validados intervalos analisados 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 CTE, o intervalo analisado da consulta CTE é validado.

No exemplo seguinte, as células SingerId e SingerInfo das linhas onde SingerId > 5 são validadas.

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

Use em subconsultas

Pode usar a cláusula FOR UPDATE numa consulta de nível exterior que tenha uma ou mais subconsultas. Os intervalos analisados pela consulta de nível superior e nas subconsultas são validados, exceto nas subconsultas de expressões.

A seguinte consulta valida as células SingerId e SingerInfo para linhas onde SingerId > 5.

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

A seguinte consulta não valida nenhuma célula na tabela Albums porque está numa subconsulta de expressão. As células SingerId e SingerInfo das linhas devolvidas pela subconsulta de expressão são validadas.

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

Use para consultar vistas

Pode usar a cláusula FOR UPDATE para consultar uma visualização, conforme mostrado no seguinte exemplo:

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

SELECT * FROM SingerBio WHERE SingerId = 5 FOR UPDATE;

Não pode usar a cláusula FOR UPDATE quando define uma vista.

Exemplos de utilização não suportados

Os seguintes exemplos de utilização FOR UPDATE não são suportados:

  • Como um mecanismo de exclusão mútua para executar código fora do Spanner: não use o bloqueio no Spanner para garantir o acesso exclusivo a um recurso fora do Spanner. As transações podem ser anuladas pelo Spanner, por exemplo, se uma transação for repetida, quer seja explicitamente pelo código da aplicação ou implicitamente pelo código do cliente, como o controlador JDBC do Spanner, só é garantido que os bloqueios são mantidos durante a tentativa que foi confirmada.
  • Em combinação com a sugestão LOCK_SCANNED_RANGES: Não pode usar a cláusula FOR UPDATE e a sugestão LOCK_SCANNED_RANGES na mesma consulta, ou o Spanner devolve um erro. Para mais informações, consulte Comparação com a sugestão LOCK_SCANNED_RANGES.
  • Em consultas de pesquisa de texto completo: não pode usar a cláusula FOR UPDATE em consultas que usam índices de pesquisa de texto completo.
  • Em transações só de leitura: a cláusula FOR UPDATE só é válida em consultas executadas em transações de leitura/escrita.
  • Em declarações DDL: não pode usar a cláusula FOR UPDATE em consultas em declarações DDL, que são armazenadas para execução posterior. Por exemplo, não pode usar a cláusula FOR UPDATE quando define uma vista.

O que se segue