Mecanismos de control de acceso concurrente a los datos en RDBMS


Qué hay en este artículo ⌄
  • Mecanismos de control de acceso concurrente en rdbms
  • Mvcc en postgresql
  • Niveles de aislamiento de transacciones en bases de datos
  • Select for update bloqueo de registros
  • Advisory locks
  • Bloqueos predictivos
  • Proceso de vacuum

1. MVCC – Control de concurrencia multiversión

Este es el mecanismo por defecto en varias RDBMS, incluyendo Postgres. Al ejecutar operaciones UPDATE/DELETE, en lugar de sobrescribir, se crea una nueva versión del registro. Los datos antiguos se marcan como “DEAD” y serán eliminados por la operación VACUUM.

VACUUM puede ser ejecutado tanto manualmente como automáticamente (AUTOVACUUM). La eliminación de los datos “DEAD” ocurre cuando todas las transacciones activas dejan de ver las versiones antiguas.

MVCC resuelve los problemas de acceso multiproceso a nivel básico:

  • El registro no es bloqueado por los lectores; en su lugar, se crea una nueva versión de los datos
  • En el momento de la operación de escritura, los lectores ven una instantánea de los datos anteriores.

Esto ocurre sin bloqueos de lectura, pero los cambios pueden bloquearse entre sí. En tal caso, el comportamiento dependerá del nivel de aislamiento de las transacciones.


2. Transacciones

Algunas tareas de coordinación de acceso a los datos pueden ser resueltas eficazmente mediante transacciones y la configuración del nivel de aislamiento de las transacciones:

  • Read Committed
  • Repeatable Read
  • Serializable

3. select for update

La construcción “select for update” – toma un lock sobre registros específicos a nivel de base de datos. El lock será tomado inmediatamente después de ejecutar esta construcción, y será liberado en el momento de COMMIT o ROLLBACK de la transacción.

La particularidad de esta construcción es que no es un bloqueo predictivo, es decir, no es posible bloquear un registro que aún no existe.


4. Advisory locks

La opción más flexible – el cliente de la base de datos debe tomar el lock por sí mismo sobre un número int específico. El identificador puede ser cualquier número, no necesariamente el id existente del registro, aunque esa es una de las opciones.

Esto se ve así:

SELECT pg_advisory_xact_lock(42);  -- Bloqueo durante la transacción actual

También hay una opción para tomar el lock durante la sesión.

En otras palabras – hemos tomado el lock con id=42. Si otro hilo intenta tomar el lock con id=43 – esto ocurrirá de inmediato, pero si es con id=42 – será necesario que la transacción original termine.