Introducción

En este tema, exploraremos las transacciones y la concurrencia en PostgreSQL. Las transacciones son fundamentales para garantizar la integridad y consistencia de los datos en una base de datos, mientras que la concurrencia se refiere a la capacidad de múltiples usuarios para acceder y modificar los datos simultáneamente sin causar inconsistencias.

Conceptos Clave

Transacciones

Una transacción es una secuencia de operaciones SQL que se ejecutan como una unidad. Las transacciones tienen las siguientes propiedades, conocidas como ACID:

  1. Atomicidad: Todas las operaciones dentro de una transacción se completan con éxito o ninguna lo hace.
  2. Consistencia: Una transacción lleva la base de datos de un estado válido a otro estado válido.
  3. Aislamiento: Las operaciones de una transacción son invisibles para otras transacciones hasta que se completan.
  4. Durabilidad: Una vez que una transacción se ha completado, sus cambios son permanentes, incluso en caso de fallos del sistema.

Concurrencia

La concurrencia se refiere a la capacidad de múltiples transacciones para acceder y modificar la base de datos al mismo tiempo. PostgreSQL utiliza varios mecanismos para manejar la concurrencia, incluyendo:

  • Bloqueos (Locks): Controlan el acceso simultáneo a los datos.
  • Control de Concurrencia Multiversión (MVCC): Permite que múltiples transacciones lean y escriban en la base de datos sin interferir entre sí.

Transacciones en PostgreSQL

Iniciando y Finalizando Transacciones

En PostgreSQL, puedes iniciar una transacción con BEGIN y finalizarla con COMMIT o ROLLBACK.

BEGIN;

-- Operaciones SQL
INSERT INTO productos (nombre, precio) VALUES ('Producto A', 100);
UPDATE inventario SET cantidad = cantidad - 1 WHERE producto_id = 1;

COMMIT;

Si ocurre un error y deseas deshacer todas las operaciones dentro de la transacción, puedes usar ROLLBACK.

BEGIN;

-- Operaciones SQL
INSERT INTO productos (nombre, precio) VALUES ('Producto B', 200);
UPDATE inventario SET cantidad = cantidad - 1 WHERE producto_id = 2;

ROLLBACK;

Aislamiento de Transacciones

PostgreSQL soporta varios niveles de aislamiento de transacciones:

  1. Read Uncommitted: Las transacciones pueden ver cambios no confirmados de otras transacciones.
  2. Read Committed: Las transacciones solo ven cambios confirmados.
  3. Repeatable Read: Las transacciones ven un estado consistente de la base de datos desde el inicio de la transacción.
  4. Serializable: Las transacciones se ejecutan de manera que el resultado es el mismo que si se hubieran ejecutado secuencialmente.

Puedes establecer el nivel de aislamiento con SET TRANSACTION.

SET TRANSACTION ISOLATION LEVEL REPEATABLE READ;

BEGIN;

-- Operaciones SQL
SELECT * FROM productos WHERE precio > 50;

COMMIT;

Concurrencia en PostgreSQL

Control de Concurrencia Multiversión (MVCC)

MVCC permite que múltiples transacciones lean y escriban en la base de datos sin bloquearse entre sí. Cada transacción ve una "instantánea" consistente de la base de datos en el momento en que comenzó.

Bloqueos (Locks)

PostgreSQL utiliza varios tipos de bloqueos para manejar la concurrencia:

  • Row-level locks: Bloquean filas específicas.
  • Table-level locks: Bloquean tablas completas.
  • Advisory locks: Bloqueos definidos por el usuario para propósitos específicos.

Ejemplo de Bloqueo de Fila

BEGIN;

-- Bloquea la fila con id = 1
SELECT * FROM productos WHERE id = 1 FOR UPDATE;

-- Operaciones SQL
UPDATE productos SET precio = 150 WHERE id = 1;

COMMIT;

Deadlocks

Un deadlock ocurre cuando dos o más transacciones se bloquean mutuamente esperando que la otra libere un recurso. PostgreSQL detecta automáticamente los deadlocks y aborta una de las transacciones involucradas.

Ejercicios Prácticos

Ejercicio 1: Transacción Básica

  1. Inicia una transacción.
  2. Inserta un nuevo producto en la tabla productos.
  3. Actualiza el inventario para reflejar la nueva cantidad del producto.
  4. Confirma la transacción.
BEGIN;

INSERT INTO productos (nombre, precio) VALUES ('Producto C', 300);
UPDATE inventario SET cantidad = cantidad + 10 WHERE producto_id = 3;

COMMIT;

Ejercicio 2: Manejo de Concurrencia

  1. Inicia una transacción y selecciona una fila para actualizarla.
  2. En otra sesión, intenta seleccionar la misma fila para actualizarla.
  3. Observa el comportamiento y resuelve cualquier conflicto.
-- Sesión 1
BEGIN;

SELECT * FROM productos WHERE id = 2 FOR UPDATE;

-- Operaciones SQL
UPDATE productos SET precio = 250 WHERE id = 2;

COMMIT;

-- Sesión 2
BEGIN;

SELECT * FROM productos WHERE id = 2 FOR UPDATE;

-- Operaciones SQL
UPDATE productos SET precio = 260 WHERE id = 2;

COMMIT;

Conclusión

En esta sección, hemos cubierto los conceptos fundamentales de las transacciones y la concurrencia en PostgreSQL. Aprendimos cómo iniciar y finalizar transacciones, los niveles de aislamiento, y cómo PostgreSQL maneja la concurrencia utilizando MVCC y bloqueos. Estos conceptos son esenciales para garantizar la integridad y consistencia de los datos en aplicaciones de bases de datos concurrentes. En el próximo módulo, exploraremos características avanzadas de PostgreSQL, como vistas, triggers y procedimientos almacenados.

Curso de PostgreSQL

Módulo 1: Introducción a PostgreSQL

Módulo 2: Operaciones Básicas de SQL

Módulo 3: Consultas Avanzadas de SQL

Módulo 4: Diseño de Bases de Datos y Normalización

Módulo 5: Características Avanzadas de PostgreSQL

Módulo 6: Ajuste de Rendimiento y Optimización

Módulo 7: Seguridad y Gestión de Usuarios

Módulo 8: Trabajando con JSON y Características NoSQL

Módulo 9: Extensiones y Herramientas Avanzadas

Módulo 10: Estudios de Caso y Aplicaciones del Mundo Real

© Copyright 2024. Todos los derechos reservados