Curso de SQL completo: SELECT, JOIN, agregaciones, índices y transacciones (2026)

Una transacción es un conjunto de operaciones SQL que se ejecutan como una unidad indivisible: o se completan todas, o no se ejecuta ninguna. Son la herramienta que garantiza la consistencia de los datos cuando varias tablas se modifican juntas o cuando múltiples usuarios operan sobre los mismos datos al mismo tiempo.

En este capítulo cubrimos las propiedades ACID, la sintaxis de transacciones en MySQL, los niveles de aislamiento y los bloqueos. El motor InnoDB (predeterminado en MySQL desde la versión 5.5) es transaccional; MyISAM no soporta transacciones.

Las cuatro propiedades ACID

Propiedad

Significado

Atomicidad

Todo o nada: si una instrucción falla, se deshace todo el bloque.

Consistencia

La BD pasa de un estado válido a otro estado válido; nunca queda a medias.

Isolamiento

Las transacciones concurrentes no se interfieren entre sí.

Durabilidad

Un COMMIT confirmado sobrevive a fallos del sistema (se guarda en disco).

Sintaxis básica

-- Por defecto, MySQL opera en autocommit: cada instrucción es su propia transacción
-- Para agrupar varias instrucciones en una transacción:

START TRANSACTION;  -- o equivalentemente: BEGIN;

    -- Crear el pedido
    INSERT INTO pedidos (id_cliente, estado) VALUES (1, 'pendiente');
    SET @pedido_id = LAST_INSERT_ID();

    -- Añadir líneas
    INSERT INTO lineas_pedido (id_pedido, id_producto, cantidad, precio_ud)
    VALUES (@pedido_id, 1, 2, 59.99);

    INSERT INTO lineas_pedido (id_pedido, id_producto, cantidad, precio_ud)
    VALUES (@pedido_id, 2, 5, 8.99);

    -- Actualizar el total del pedido
    UPDATE pedidos
    SET total = (
        SELECT SUM(cantidad * precio_ud) FROM lineas_pedido WHERE id_pedido = @pedido_id
    )
    WHERE id = @pedido_id;

COMMIT;  -- confirmar: todos los cambios se guardan permanentemente

-- Si algo falla antes del COMMIT:
ROLLBACK;  -- deshacer todos los cambios desde el START TRANSACTION

SAVEPOINT: puntos de control dentro de la transacción

START TRANSACTION;

    INSERT INTO pedidos (id_cliente, estado) VALUES (2, 'pendiente');
    SAVEPOINT sp1;

    -- Si este INSERT falla, podemos volver al savepoint sin deshacer todo
    INSERT INTO lineas_pedido (id_pedido, id_producto, cantidad, precio_ud)
    VALUES (LAST_INSERT_ID(), 99, 1, 0.00);  -- producto 99 podría no existir

ROLLBACK TO SAVEPOINT sp1;  -- vuelve al estado después del primer INSERT
-- El pedido sigue existiendo; solo se deshizo el INSERT de línea de pedido

COMMIT;

Niveles de aislamiento

El nivel de aislamiento controla qué puede leer una transacción de los cambios no confirmados de otras transacciones concurrentes:

Nivel

Dirty read

Non-repeatable read

Phantom read

READ UNCOMMITTED

Posible

Posible

Posible

READ COMMITTED

No

Posible

Posible

REPEATABLE READ (defecto MySQL)

No

No

No* (InnoDB)

SERIALIZABLE

No

No

No

-- Ver el nivel actual
SELECT @@transaction_isolation;

-- Cambiar para la sesión actual
SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED;

Deadlocks: bloqueos mutuos

Un deadlock ocurre cuando dos transacciones se bloquean mutuamente esperando que la otra libere un recurso. MySQL detecta los deadlocks automáticamente y aborta una de las transacciones (la que haya hecho menos trabajo). La aplicación debe relanzar la operación cuando recibe el error 1213 (Deadlock found).

-- Para minimizar deadlocks:
-- 1. Bloquear siempre las tablas en el mismo orden
-- 2. Mantener las transacciones lo más cortas posible
-- 3. Usar índices para que los bloqueos de fila sean más selectivos

-- Ver el último deadlock detectado por InnoDB:
SHOW ENGINE INNODB STATUS\G

COMPARTE ESTE ARTÍCULO

COMPARTIR EN FACEBOOK
COMPARTIR EN TWITTER
COMPARTIR EN LINKEDIN
COMPARTIR EN WHATSAPP