En esta página, se describe cómo usar la cláusula FOR UPDATE
en el aislamiento de lectura repetible.
El mecanismo de bloqueo de la cláusula FOR UPDATE
es diferente para el aislamiento de lectura repetible y serializable. A diferencia del aislamiento serializable, la cláusula FOR UPDATE
no adquiere bloqueos en el aislamiento de lectura repetible. Para obtener más información sobre los bloqueos en FOR UPDATE
, consulta Usa SELECT FOR UPDATE en aislamiento serializable.
Para obtener información sobre cómo usar la cláusula FOR UPDATE
, consulta las guías de referencia de GoogleSQL y PostgreSQL de FOR UPDATE
.
Por qué usar la cláusula FOR UPDATE
Cuando una transacción se ejecuta con aislamiento de lectura repetible, los datos consultados por la instrucción SELECT
siempre se devuelven en la marca de tiempo de la instantánea establecida para la transacción. Si la transacción realiza actualizaciones basadas en los datos consultados, podría haber problemas de corrección si una transacción simultánea también actualiza los datos consultados. Para obtener más información, consulta Conflictos de lectura y escritura, y corrección.
Para asegurarte de que los datos consultados por la instrucción SELECT
sigan siendo válidos cuando se confirme la transacción, puedes usar una cláusula FOR UPDATE
con aislamiento de lectura repetible. El uso de FOR UPDATE
garantiza la corrección de la transacción a pesar de los conflictos de lectura y escritura en los que otra transacción podría haber modificado los datos entre el momento en que se leyeron y el momento en que se modificaron.
Sintaxis de las consultas
En esta sección, se proporciona orientación sobre la sintaxis de las consultas cuando se usa la cláusula FOR UPDATE
.
El uso más común es en una instrucción SELECT
de nivel superior. Por ejemplo:
SELECT SingerId, SingerInfo
FROM Singers WHERE SingerID = 5
FOR UPDATE;
La cláusula FOR UPDATE
garantiza que los datos consultados por la instrucción SELECT
y SingerID = 5
sigan siendo válidos cuando se confirme la transacción, lo que evita problemas de corrección que podrían surgir si una transacción simultánea actualiza los datos consultados.
Uso en sentencias WITH
La cláusula FOR UPDATE
no verifica los rangos analizados dentro de la declaración WITH
cuando especificas FOR UPDATE
en la consulta de nivel externo de la declaración WITH
.
En la siguiente consulta, no se validan los rangos analizados porque FOR UPDATE
no se propaga a la consulta de expresiones de tabla comunes (CTE).
WITH s AS (SELECT SingerId, SingerInfo FROM Singers WHERE SingerID > 5)
SELECT * FROM s
FOR UPDATE;
Si se especifica la cláusula FOR UPDATE
en la consulta de CTE, se valida el rango analizado de la consulta de CTE.
En el siguiente ejemplo, se validan las celdas SingerId
y SingerInfo
para las filas en las que SingerId > 5
.
WITH s AS
(SELECT SingerId, SingerInfo FROM Singers WHERE SingerId > 5 FOR UPDATE)
SELECT * FROM s;
Uso en subconsultas
Puedes usar la cláusula FOR UPDATE
en una consulta de nivel externo que tenga una o más subconsultas. Los rangos analizados por la consulta de nivel superior y dentro de las subconsultas se validan, excepto en las subconsultas de expresión.
La siguiente consulta valida las celdas SingerId
y SingerInfo
para las filas en las que SingerId > 5.
(SELECT SingerId, SingerInfo FROM Singers WHERE SingerId > 5) AS t
FOR UPDATE;
La siguiente consulta no valida ninguna celda en la tabla Albums
porque se encuentra dentro de una subconsulta de expresión. Se validan las celdas SingerId
y SingerInfo
de las filas que muestra la subconsulta de la expresión.
SELECT SingerId, SingerInfo
FROM Singers
WHERE SingerId = (SELECT SingerId FROM Albums WHERE MarketingBudget > 100000)
FOR UPDATE;
Se usa para consultar vistas.
Puedes usar la cláusula FOR UPDATE
para consultar una vista, como se muestra en el siguiente ejemplo:
CREATE VIEW SingerBio AS SELECT SingerId, FullName, SingerInfo FROM Singers;
SELECT * FROM SingerBio WHERE SingerId = 5 FOR UPDATE;
No puedes usar la cláusula FOR UPDATE
cuando defines una vista.
Casos de uso no admitidos
Los siguientes casos de uso de FOR UPDATE
no son compatibles:
- Como mecanismo de exclusión mutua para ejecutar código fuera de Spanner: No uses el bloqueo en Spanner para garantizar el acceso exclusivo a un recurso fuera de Spanner. Spanner puede anular las transacciones, por ejemplo, si se reintenta una transacción, ya sea de forma explícita por el código de la aplicación o de forma implícita por el código del cliente, como el controlador JDBC de Spanner. Solo se garantiza que las exclusiones se mantengan durante el intento que se confirmó.
- En combinación con la sugerencia
LOCK_SCANNED_RANGES
: No puedes usar la cláusulaFOR UPDATE
y la sugerenciaLOCK_SCANNED_RANGES
en la misma consulta. De lo contrario, Spanner devolverá un error. Para obtener más información, consulta Comparación con la sugerenciaLOCK_SCANNED_RANGES
. - En las consultas de búsqueda en el texto completo: No puedes usar la cláusula
FOR UPDATE
en las consultas que usan índices de búsqueda en el texto completo. - En transacciones de solo lectura: La cláusula
FOR UPDATE
solo es válida en las consultas que se ejecutan dentro de transacciones de lectura y escritura. - En las declaraciones DDL: No puedes usar la cláusula
FOR UPDATE
en las consultas dentro de las declaraciones DDL, que se almacenan para su ejecución posterior. Por ejemplo, no puedes usar la cláusulaFOR UPDATE
cuando defines una vista.
Pasos siguientes
- Aprende a usar la cláusula
FOR UPDATE
en GoogleSQL y PostgreSQL. - Obtén más información para usar SELECT FOR UPDATE en el aislamiento serializable.
- Obtén más información sobre la sugerencia de
LOCK_SCANNED_RANGES
. - Obtén información sobre el bloqueo en Spanner.