Lock:transactionid
El evento Lock:transactionid
se produce cuando una transacción espera un bloqueo a nivel de fila.
Versiones del motor admitidas
Esta información de eventos de espera es compatible con todas las versiones de RDS para PostgreSQL.
Contexto
El evento Lock:transactionid
ocurre cuando una transacción intenta adquirir un bloqueo a nivel de fila que ya fue otorgado a una transacción que se está ejecutando al mismo tiempo. La sesión que muestra el evento de espera Lock:transactionid
se encuentra bloqueada debido a este bloqueo. Después de que la transacción bloqueada termine con una instrucción COMMIT
o ROLLBACK
, la transacción bloqueada puede continuar.
La semántica de control de concurrencia multiversión de RDS para PostgreSQL garantiza que los lectores no bloqueen a los escritores y que los escritores no bloqueen a los lectores. ara que se produzcan conflictos en las filas, las transacciones bloqueantes y bloqueadas deben emitir instrucciones conflictivas de los siguientes tipos:
-
UPDATE
-
SELECT … FOR UPDATE
-
SELECT … FOR KEY SHARE
La instrucción SELECT … FOR KEY SHARE
es un caso especial. La base de datos utiliza la cláusula FOR KEY
SHARE
para optimizar el rendimiento de la integridad referencial. Un bloqueo en una fila puede bloquear los comandos INSERT
, UPDATE
y DELETE
en otras tablas que hacen referencia a la fila.
Causas probables del aumento de las esperas
Cuando este evento aparece más de lo normal, la causa suele ser instrucciones UPDATE
, SELECT …
FOR UPDATE
o SELECT … FOR KEY SHARE
combinadas con las siguientes condiciones.
Gran concurrencia
RDS para PostgreSQL puede utilizar una semántica de bloqueo pormenorizada por filas. La probabilidad de conflictos entre filas aumenta cuando se cumplen las siguientes condiciones:
-
Una carga de trabajo de gran concurrencia compite por las mismas filas.
-
Aumenta la concurrencia.
Inactividad en la transacción
A veces la columna pg_stat_activity.state
muestra el valor idle in transaction
. Este valor aparece para las sesiones que iniciaron una transacción, pero aún no han emitido un COMMIT
o ROLLBACK
. Si el valor de pg_stat_activity.state
no se encuentra active
, la consulta mostrada en pg_stat_activity
es la más reciente en terminar de ejecutarse. La sesión de bloqueo no se encuentra en proceso activo de una consulta porque una transacción abierta está manteniendo un bloqueo.
Si una transacción inactiva adquirió un bloqueo entre filas, puede impedir que otras sesiones lo adquieran. Esta condición conduce a la aparición frecuente del evento de espera Lock:transactionid
. Para diagnosticar el problema, examine la salida de pg_stat_activity
y pg_locks
.
Transacciones de larga duración
Las transacciones que se ejecutan durante mucho tiempo obtienen bloqueos durante mucho tiempo. Estos bloqueos de larga duración pueden bloquear la ejecución de otras transacciones.
Acciones
El bloqueo de filas es un conflicto entre las instrucciones UPDATE
, SELECT … FOR
UPDATE
, o SELECT … FOR KEY SHARE
. Antes de intentar una solución, averigüe cuándo se están ejecutando estas instrucciones en la misma fila. Utilice esta información para elegir una estrategia descrita en las siguientes secciones.
Temas
Responder a la alta concurrencia
Si el problema es la concurrencia, pruebe una de las siguientes técnicas:
-
Reduzca la concurrencia en la aplicación. Por ejemplo, disminuya el número de sesiones activas.
-
Implemente un grupo de conexiones. Para saber cómo agrupar conexiones con RDS Proxy, consulte Uso de Amazon RDS Proxy .
-
Diseñe la aplicación o el modelo de datos para evitar las instrucciones
UPDATE
ySELECT … FOR UPDATE
en conflicto. También puede disminuir el número de claves foráneas a las que se accede mediante instruccionesSELECT … FOR KEY SHARE
.
Responder a las transacciones inactivas
Si pg_stat_activity.state
muestra una transacción idle in transaction
, utilice las siguientes estrategias:
-
Active la confirmación automática siempre que sea posible. Este enfoque evita que las transacciones bloqueen otras transacciones mientras esperan un
COMMIT
oROLLBACK
. -
Busque rutas de código en las que falten
COMMIT
,ROLLBACK
oEND
. -
Asegúrese de que la lógica de manejo de excepciones en su aplicación siempre tiene una ruta hacia
end of transaction
válido. -
Asegúrese de que su aplicación procesa los resultados de la consulta después de finalizar la transacción con
COMMIT
oROLLBACK
.
Responder a las transacciones de larga duración
Si las transacciones de larga duración provocan la aparición frecuente de Lock:transactionid
, pruebe las siguientes estrategias:
-
Mantenga los bloqueos de filas fuera de las transacciones de larga duración.
-
Limite la longitud de las consultas mediante la implementación de confirmación automática siempre que sea posible.