Transacciones en SQL: Qué son, ACID y cómo usarlas correctamente

D
DanisCh
16 min de lectura
Transacciones en SQL: Qué son, ACID y cómo usarlas correctamente
SQL

Imagina que haces una transferencia bancaria. El banco descuenta $500 de tu cuenta y, en ese exacto instante, el servidor falla antes de acreditar el dinero en la cuenta destino. ¿Qué pasa con esos $500? ¿Desaparecen?

Sin transacciones: sí, podrían desaparecer. Con transacciones: imposible. O la operación completa se ejecuta correctamente, o ninguna parte de ella surte efecto.

Las transacciones son el mecanismo que garantiza que las bases de datos mantengan su integridad incluso ante fallos, errores o accesos simultáneos. Son la razón por la que confías tus datos más críticos a una base de datos relacional. Y entenderlas en profundidad es lo que separa a un desarrollador junior de uno senior.


¿Qué es una transacción en SQL?

Una transacción es una unidad lógica de trabajo que agrupa una o más operaciones SQL (INSERT, UPDATE, DELETE) que deben ejecutarse de forma conjunta: o todas tienen éxito, o ninguna se aplica.

La analogía más usada — y la más precisa — es la transferencia bancaria:

Una transferencia de Ana a Luis tiene DOS pasos:
  Paso 1: Descontar 500 € de la cuenta de Ana
  Paso 2: Añadir 500 € a la cuenta de Luis

Sin transacción:
  Si el servidor falla entre el paso 1 y el 2:
  → Ana pierde 500 € que Luis nunca recibe ❌ datos corruptos

Con transacción:
  Si algo falla en cualquier punto:
  → Se revierten TODOS los cambios como si nada hubiera ocurrido ✅
  → La base de datos vuelve al estado exacto anterior a la transferencia

Otro ejemplo cotidiano: reservar un vuelo. El sistema debe:

  1. Marcar el asiento como ocupado
  2. Cobrar el importe al cliente
  3. Generar la factura
  4. Enviar el correo de confirmación

Si cualquiera de esos pasos falla, ¿quieres que el asiento quede ocupado sin cobro, o que se cobre sin asiento asignado? Con una transacción bien diseñada, o todo ocurre o nada ocurre.


Los comandos básicos de una transacción

BEGIN;          -- inicia la transacción (también: START TRANSACTION)
  [operaciones SQL]
COMMIT;         -- confirma todos los cambios permanentemente
-- o
ROLLBACK;       -- deshace todos los cambios desde el BEGIN
-- Ejemplo: transferencia bancaria
BEGIN;

  -- Paso 1: descontar de la cuenta origen
  UPDATE cuentas
  SET saldo = saldo - 500
  WHERE id = 1;

  -- Paso 2: acreditar en la cuenta destino
  UPDATE cuentas
  SET saldo = saldo + 500
  WHERE id = 2;

COMMIT;  -- ← ambos cambios se guardan permanentemente

-- Si algo va mal:
-- ROLLBACK;  ← ambos cambios se revierten, como si no hubieran ocurrido

El autocommit — el modo por defecto que te puede sorprender

Por defecto, MySQL y PostgreSQL trabajan en modo autocommit: cada instrucción SQL individual se trata como una transacción propia y se confirma automáticamente al ejecutarse.

-- Con autocommit activado (modo por defecto):
UPDATE productos SET stock = stock - 1 WHERE id = 42;
-- Este cambio se confirma INMEDIATAMENTE, sin necesidad de COMMIT
-- No hay forma de revertirlo con ROLLBACK

-- Para usar transacciones explícitas, tienes dos opciones:

-- Opción 1: iniciar con BEGIN (desactiva autocommit temporalmente)
BEGIN;
  UPDATE productos SET stock = stock - 1 WHERE id = 42;
  UPDATE pedidos SET estado = 'procesando' WHERE id = 101;
COMMIT;

-- Opción 2: desactivar autocommit para toda la sesión (MySQL)
SET autocommit = 0;
UPDATE productos SET stock = stock - 1 WHERE id = 42;
UPDATE pedidos SET estado = 'procesando' WHERE id = 101;
COMMIT;  -- ahora el COMMIT es obligatorio

💡 Diferencia MySQL vs PostgreSQL: En PostgreSQL, BEGIN y START TRANSACTION son equivalentes. En MySQL, la sintaxis más común es START TRANSACTION, aunque BEGIN también funciona.


Las 4 propiedades ACID

ACID es el acrónimo que define las cuatro propiedades que debe cumplir toda transacción correctamente implementada. Son el estándar de oro que hace que los sistemas relacionales sean confiables para datos críticos.

⚛️ A — Atomicidad (Atomicity)

"Todo o nada." Una transacción es atómica: o todas sus operaciones se ejecutan correctamente, o ninguna de ellas surte efecto. No existe un estado intermedio.

BEGIN;

  UPDATE cuentas SET saldo = saldo - 500 WHERE id = 1;
  -- ↑ Este cambio está "pendiente", no confirmado

  -- Imagina que aquí ocurre un error de red o un fallo del servidor

  UPDATE cuentas SET saldo = saldo + 500 WHERE id = 2;
  -- ↑ Esta operación nunca se ejecuta

-- El motor de BD detecta la transacción incompleta
-- y ejecuta automáticamente un ROLLBACK implícito

-- Resultado: la base de datos queda exactamente como estaba antes del BEGIN
-- La atomicidad garantiza que no hay "dinero perdido en el aire"

La atomicidad se implementa mediante un log de transacciones (transaction log o WAL en PostgreSQL: Write-Ahead Log). Antes de aplicar cualquier cambio, el motor registra qué operaciones forman parte de la transacción. Si ocurre un fallo, el motor lee el log y revierte los cambios al reiniciarse.

🎯 C — Consistencia (Consistency)

"De un estado válido a otro estado válido." Una transacción lleva la base de datos de un estado consistente a otro estado consistente, respetando todas las restricciones definidas: claves foráneas, checks, unique, not null...

-- Supongamos esta restricción:
-- saldo en cuentas siempre debe ser >= 0 (CHECK constraint)

CREATE TABLE cuentas (
    id     INT PRIMARY KEY,
    saldo  DECIMAL(10,2) CHECK (saldo >= 0)  -- restricción de consistencia
);

BEGIN;
  -- Ana tiene 100 €, intenta transferir 200 €
  UPDATE cuentas SET saldo = saldo - 200 WHERE id = 1;
  -- ↑ El saldo quedaría en -100 → viola la restricción CHECK

  UPDATE cuentas SET saldo = saldo + 200 WHERE id = 2;
COMMIT;
-- ERROR: new row violates check constraint
-- La transacción completa se revierte → consistencia preservada ✅

-- La base de datos NUNCA queda en un estado que viole sus restricciones

🔒 I — Aislamiento (Isolation)

"Las transacciones concurrentes no se interfieren entre sí." Cuando múltiples transacciones se ejecutan simultáneamente, cada una debe operar como si fuera la única que existe en ese momento.

-- Problema sin aislamiento: "lectura sucia" (dirty read)

Transacción A:                    Transacción B:
BEGIN;
UPDATE cuentas                    BEGIN;
SET saldo = saldo - 500           SELECT saldo FROM cuentas
WHERE id = 1;  -- saldo: 1000→500 WHERE id = 1;  -- ← lee 500
                                  -- B ve un cambio que A no ha confirmado
ROLLBACK;  -- A se revierte       -- Si A hace rollback, B usó datos falsos
-- saldo vuelve a 1000            -- ¡B tomó una decisión basada en datos incorrectos!

El aislamiento previene estos problemas. El nivel exacto de aislamiento es configurable — más sobre esto en la sección de niveles de aislamiento.

💾 D — Durabilidad (Durability)

"Los cambios confirmados sobreviven a cualquier fallo." Una vez que se ejecuta COMMIT, los cambios son permanentes. Ni un corte de luz, ni un fallo del servidor, ni un crash de la aplicación puede borrarlos.

BEGIN;
  INSERT INTO pedidos (cliente_id, total, fecha)
  VALUES (101, 299.99, NOW());

  UPDATE inventario SET stock = stock - 1 WHERE producto_id = 42;
COMMIT;  -- ← a partir de aquí, estos cambios son PERMANENTES

-- Si el servidor falla 1 microsegundo después del COMMIT:
-- Al reiniciarse, el motor lee el WAL (Write-Ahead Log)
-- y encuentra que la transacción estaba completada
-- Los datos están protegidos ✅

-- La durabilidad se implementa mediante:
-- - Escritura en disco antes de confirmar (WAL/Redo Log)
-- - Sincronización con fsync para garantizar escritura física
-- - Backups y replicación para alta disponibilidad

SAVEPOINT — puntos de guardado dentro de una transacción

Un SAVEPOINT es un punto de guardado dentro de una transacción que permite hacer un ROLLBACK parcial sin deshacer toda la transacción. Es especialmente útil en operaciones complejas con múltiples pasos.

BEGIN;

  -- Paso 1: crear el pedido
  INSERT INTO pedidos (cliente_id, fecha, total)
  VALUES (101, NOW(), 0);

  SAVEPOINT pedido_creado;  -- ← punto de guardado

  -- Paso 2: añadir los productos al pedido
  INSERT INTO detalle_pedidos (pedido_id, producto_id, cantidad)
  VALUES (LAST_INSERT_ID(), 42, 2);

  SAVEPOINT detalle_añadido;  -- ← otro punto de guardado

  -- Paso 3: actualizar el stock
  UPDATE productos SET stock = stock - 2 WHERE id = 42;

  -- Supongamos que detectamos que el stock quedaría negativo
  -- En lugar de cancelar todo el pedido, solo revertimos el paso 3:
  ROLLBACK TO SAVEPOINT detalle_añadido;
  -- ← volvemos al estado después del paso 2

  -- Podemos tomar otra acción (pedido con stock insuficiente)
  UPDATE pedidos SET estado = 'stock_insuficiente' WHERE id = LAST_INSERT_ID();

COMMIT;  -- guardamos el pedido aunque no pudo procesarse el stock

-- RELEASE SAVEPOINT libera el savepoint sin hacer rollback
-- RELEASE SAVEPOINT pedido_creado;

Los niveles de aislamiento — el dial entre rendimiento y consistencia

El aislamiento completo entre transacciones garantiza la máxima consistencia pero a un costo de rendimiento. Los niveles de aislamiento permiten ajustar este equilibrio según las necesidades de la aplicación.

Los problemas de concurrencia que los niveles resuelven

1. DIRTY READ (lectura sucia)
   → Leer datos de una transacción que aún NO ha hecho COMMIT
   → Esos datos pueden revertirse y nunca existir realmente

2. NON-REPEATABLE READ (lectura no repetible)
   → Dentro de una misma transacción, leer el mismo dato dos veces
     y obtener valores diferentes porque otra transacción lo modificó
   → Primera lectura: saldo = 1000. Segunda lectura: saldo = 800

3. PHANTOM READ (lectura fantasma)
   → Una consulta devuelve más o menos filas en dos ejecuciones
     dentro de la misma transacción porque otra transacción
     insertó o eliminó filas
   → Primera consulta: 5 productos en stock. Segunda: 4 productos

Los 4 niveles de aislamiento SQL estándar

NivelDirty ReadNon-Repeatable ReadPhantom ReadRendimiento
READ UNCOMMITTED✅ Posible✅ Posible✅ Posible⚡ Máximo
READ COMMITTED❌ Prevenido✅ Posible✅ Posible🟡 Alto
REPEATABLE READ❌ Prevenido❌ Prevenido✅ Posible🟠 Medio
SERIALIZABLE❌ Prevenido❌ Prevenido❌ Prevenido🔴 Bajo
-- Configurar el nivel de aislamiento en MySQL
SET TRANSACTION ISOLATION LEVEL READ COMMITTED;
BEGIN;
  -- operaciones...
COMMIT;

-- Configurar en PostgreSQL
BEGIN;
SET TRANSACTION ISOLATION LEVEL REPEATABLE READ;
  -- operaciones...
COMMIT;

-- Ver el nivel actual:
-- MySQL:
SELECT @@transaction_isolation;

-- PostgreSQL:
SHOW transaction_isolation;

¿Cuál usar en la práctica?

READ UNCOMMITTED:
  → Casi nunca se usa. El riesgo de dirty reads es inaceptable
    en casi cualquier aplicación real.

READ COMMITTED:
  → El nivel por defecto de PostgreSQL y Oracle
  → Ideal para la mayoría de aplicaciones web
  → Previene dirty reads, permite non-repeatable reads

REPEATABLE READ:
  → El nivel por defecto de MySQL (InnoDB)
  → Ideal cuando necesitas que una transacción larga vea
    datos consistentes durante toda su ejecución
  → Informes largos, cálculos financieros complejos

SERIALIZABLE:
  → El nivel más estricto — máxima consistencia
  → Ideal para transacciones financieras críticas
  → Más lento — mayor contención entre transacciones
  → Úsalo cuando la consistencia es más importante que el rendimiento

Ejemplo completo real: sistema de reservas de vuelo

-- ============================================================
-- SISTEMA DE RESERVAS CON MANEJO COMPLETO DE TRANSACCIONES
-- ============================================================

-- Tablas del sistema
CREATE TABLE vuelos (
    id          INT PRIMARY KEY,
    origen      VARCHAR(3),
    destino     VARCHAR(3),
    fecha       DATE,
    asientos_disponibles INT,
    precio      DECIMAL(10,2)
);

CREATE TABLE reservas (
    id          INT PRIMARY KEY AUTO_INCREMENT,
    vuelo_id    INT,
    pasajero_id INT,
    asiento     VARCHAR(5),
    total       DECIMAL(10,2),
    estado      VARCHAR(20) DEFAULT 'confirmada',
    FOREIGN KEY (vuelo_id) REFERENCES vuelos(id)
);

CREATE TABLE pagos (
    id          INT PRIMARY KEY AUTO_INCREMENT,
    reserva_id  INT,
    importe     DECIMAL(10,2),
    metodo      VARCHAR(20),
    fecha       DATETIME DEFAULT NOW()
);

-- ============================================================
-- PROCEDIMIENTO DE RESERVA CON TRANSACCIÓN COMPLETA
-- ============================================================

START TRANSACTION;

-- 1. Verificar disponibilidad (con bloqueo para evitar race conditions)
SELECT asientos_disponibles, precio
FROM vuelos
WHERE id = 42
FOR UPDATE;  -- ← bloquea la fila para esta transacción

-- Supongamos que la consulta devuelve: asientos=1, precio=299.99
-- Si asientos_disponibles = 0, haríamos ROLLBACK

-- 2. Reducir asientos disponibles
UPDATE vuelos
SET asientos_disponibles = asientos_disponibles - 1
WHERE id = 42;

-- 3. Crear la reserva
INSERT INTO reservas (vuelo_id, pasajero_id, asiento, total)
VALUES (42, 1001, '14A', 299.99);

SAVEPOINT reserva_creada;  -- punto de guardado

-- 4. Registrar el pago
INSERT INTO pagos (reserva_id, importe, metodo)
VALUES (LAST_INSERT_ID(), 299.99, 'tarjeta');

-- 5. Si todo salió bien, confirmar
COMMIT;

-- ============================================================
-- MANEJO DE ERRORES CON ROLLBACK
-- ============================================================
-- En una aplicación real, el manejo de errores sería así (pseudocódigo):

START TRANSACTION;

  UPDATE vuelos SET asientos_disponibles = asientos_disponibles - 1 WHERE id = 42;

  -- Si la actualización afectó 0 filas (vuelo sin plazas):
  IF ROW_COUNT() = 0 THEN
    ROLLBACK;
    SELECT 'Error: no hay asientos disponibles' AS mensaje;
  ELSE
    INSERT INTO reservas (vuelo_id, pasajero_id, total) VALUES (42, 1001, 299.99);
    INSERT INTO pagos (reserva_id, importe) VALUES (LAST_INSERT_ID(), 299.99);
    COMMIT;
    SELECT 'Reserva confirmada' AS mensaje;
  END IF;

Transacciones desde código de aplicación

En aplicaciones reales, las transacciones se manejan desde el código de la aplicación, no manualmente en la consola SQL. Aquí un ejemplo con Python:

# Python con psycopg2 (PostgreSQL)
import psycopg2

conn = psycopg2.connect("dbname=banco user=admin")

try:
    with conn:  # el contexto gestiona BEGIN/COMMIT/ROLLBACK automáticamente
        with conn.cursor() as cur:
            # Paso 1: verificar saldo disponible
            cur.execute("SELECT saldo FROM cuentas WHERE id = %s FOR UPDATE", (1,))
            saldo = cur.fetchone()[0]

            if saldo < 500:
                raise ValueError("Saldo insuficiente")

            # Paso 2: descontar de la cuenta origen
            cur.execute(
                "UPDATE cuentas SET saldo = saldo - %s WHERE id = %s",
                (500, 1)
            )

            # Paso 3: acreditar en la cuenta destino
            cur.execute(
                "UPDATE cuentas SET saldo = saldo + %s WHERE id = %s",
                (500, 2)
            )

            # Paso 4: registrar el movimiento
            cur.execute(
                "INSERT INTO movimientos (origen, destino, importe) VALUES (%s, %s, %s)",
                (1, 2, 500)
            )

    # Si llegamos aquí sin excepción → COMMIT automático
    print("✅ Transferencia realizada con éxito")

except ValueError as e:
    print(f"❌ Error de negocio: {e}")
    # ROLLBACK automático gracias al context manager

except psycopg2.Error as e:
    print(f"❌ Error de base de datos: {e}")
    # ROLLBACK automático

finally:
    conn.close()
// Node.js con mysql2
const mysql = require('mysql2/promise');

async function realizarTransferencia(origenId, destinoId, importe) {
    const conn = await mysql.createConnection({ host: 'localhost', database: 'banco' });

    try {
        await conn.beginTransaction();

        // Verificar saldo con bloqueo
        const [filas] = await conn.execute(
            'SELECT saldo FROM cuentas WHERE id = ? FOR UPDATE', [origenId]
        );

        if (filas[0].saldo < importe) {
            throw new Error('Saldo insuficiente');
        }

        // Descontar origen
        await conn.execute(
            'UPDATE cuentas SET saldo = saldo - ? WHERE id = ?', [importe, origenId]
        );

        // Acreditar destino
        await conn.execute(
            'UPDATE cuentas SET saldo = saldo + ? WHERE id = ?', [importe, destinoId]
        );

        await conn.commit();
        console.log('✅ Transferencia exitosa');

    } catch (error) {
        await conn.rollback();
        console.error('❌ Error:', error.message);
        throw error;

    } finally {
        conn.end();
    }
}

ACID vs BASE — dos filosofías de consistencia

Las bases de datos NoSQL de alto rendimiento suelen usar un modelo diferente llamado BASE, que es lo opuesto de ACID en cuanto a prioridades:

ACID:                              BASE:
  Atomicity (atomicidad)             Basically Available (disponibilidad básica)
  Consistency (consistencia)         Soft state (estado flexible)
  Isolation (aislamiento)            Eventually consistent (consistencia eventual)
  Durability (durabilidad)

ACID prioriza:                     BASE prioriza:
  Consistencia de datos              Disponibilidad y rendimiento
  Integridad garantizada             Escalabilidad horizontal
  Transacciones seguras              Tolerancia a inconsistencias temporales

Úsalo para:                        Úsalo para:
  Banca, finanzas, salud             Redes sociales, analytics
  Sistemas legales, contabilidad     Sistemas de caché, feeds
  E-commerce crítico                 Recomendaciones, búsquedas

💡 La realidad de 2026: muchas bases de datos modernas como MongoDB ofrecen transacciones ACID a nivel de documento y entre colecciones, acercando ambos mundos. Pero para sistemas financieros críticos, las bases de datos relacionales con ACID completo siguen siendo el estándar.


Buenas prácticas para transacciones en producción

✅ 1. Mantén las transacciones cortas

-- ❌ Transacción larga: bloquea recursos durante mucho tiempo
BEGIN;
  UPDATE productos SET precio = precio * 1.10;  -- actualiza TODOS los productos
  -- Esta operación puede tardar minutos en tablas grandes
  -- Mientras, otras transacciones esperan con los datos bloqueados
COMMIT;

-- ✅ Transacciones por lotes: actualiza en chunks pequeños
CALL actualizar_precios_en_lotes(1000);  -- 1000 productos por transacción

✅ 2. Siempre maneja errores con ROLLBACK

-- ❌ Sin manejo de errores: puede dejar la BD en estado inconsistente
BEGIN;
  UPDATE cuentas SET saldo = saldo - 500 WHERE id = 1;
  UPDATE cuentas SET saldo = saldo + 500 WHERE id = 2;
-- Si la aplicación falla aquí, la transacción queda abierta

-- ✅ Con manejo de errores explícito
BEGIN;
  -- operaciones...
  -- Si hay algún error → ROLLBACK
  -- Si todo va bien → COMMIT

✅ 3. Usa FOR UPDATE para evitar race conditions

-- Dos usuarios intentan reservar el último asiento simultáneamente
-- Sin FOR UPDATE: ambos leen "1 asiento disponible" y ambos reservan → overselling

BEGIN;
-- FOR UPDATE bloquea la fila para esta transacción
-- La segunda transacción debe esperar hasta que la primera haga COMMIT
SELECT asientos_disponibles FROM vuelos WHERE id = 42 FOR UPDATE;
  -- Ahora solo esta transacción puede leer y modificar esta fila
  -- La competidora espera...
UPDATE vuelos SET asientos_disponibles = asientos_disponibles - 1 WHERE id = 42;
INSERT INTO reservas ...;
COMMIT;
-- Ahora la segunda transacción puede leer → verá asientos=0 → cancela correctamente

✅ 4. No pongas lógica de negocio compleja dentro de la transacción

-- ❌ Llamadas a APIs externas dentro de la transacción
BEGIN;
  UPDATE cuentas SET saldo = saldo - 500 WHERE id = 1;
  CALL api_externa_enviar_email();  -- puede tardar segundos o fallar
  UPDATE cuentas SET saldo = saldo + 500 WHERE id = 2;
COMMIT;

-- ✅ Primero la transacción, luego las operaciones externas
BEGIN;
  UPDATE cuentas SET saldo = saldo - 500 WHERE id = 1;
  UPDATE cuentas SET saldo = saldo + 500 WHERE id = 2;
COMMIT;
-- Después del commit, sin transacción abierta:
enviar_email_confirmacion();

Errores comunes con transacciones

❌ Olvidar el COMMIT o el ROLLBACK

-- Si abres una transacción y no haces COMMIT ni ROLLBACK:
BEGIN;
  UPDATE productos SET stock = stock - 1 WHERE id = 42;
-- La sesión se cierra sin COMMIT → ROLLBACK automático
-- Los cambios se pierden silenciosamente

❌ Asumir que BEGIN está implícito

-- Si autocommit está activado (por defecto):
UPDATE cuentas SET saldo = saldo - 500 WHERE id = 1;
-- Este cambio ya se confirmó ← ya no puedes revertirlo

-- Para usar transacciones, siempre debes usar BEGIN explícitamente

❌ Transacciones anidadas (no existen en SQL estándar)

-- ❌ Esto NO hace lo que parece:
BEGIN;
  UPDATE cuentas SET saldo = saldo - 500 WHERE id = 1;
  BEGIN;  -- ← en MySQL, esto hace COMMIT implícito de la transacción anterior
    UPDATE cuentas SET saldo = saldo + 500 WHERE id = 2;
  COMMIT;
COMMIT;

-- ✅ Para anidamiento, usa SAVEPOINT en su lugar

Resumen: lo que aprendiste hoy

  • ✅ Una transacción agrupa operaciones SQL que se ejecutan como una unidad — todo o nada
  • ✅ Los comandos básicos son: BEGIN (o START TRANSACTION), COMMIT y ROLLBACK
  • ✅ Por defecto, las bases de datos trabajan en modo autocommit — cada instrucción es una transacción propia
  • Atomicidad — todo o nada. Implementada con el Write-Ahead Log
  • Consistencia — siempre de un estado válido a otro. Las restricciones nunca se violan
  • Aislamiento — las transacciones concurrentes no se interfieren entre sí
  • Durabilidad — los cambios confirmados son permanentes aunque falle el servidor
  • SAVEPOINT permite hacer rollback parcial sin deshacer toda la transacción
  • ✅ Los 4 niveles de aislamiento van de READ UNCOMMITTED (más rápido) a SERIALIZABLE (más consistente)
  • FOR UPDATE bloquea filas para evitar race conditions en entornos concurrentes
  • ✅ ACID prioriza consistencia; BASE (NoSQL) prioriza disponibilidad y rendimiento
  • ✅ Mantén las transacciones cortas, maneja errores con ROLLBACK y nunca pongas llamadas externas dentro de una transacción

🧪 ¿Tienes los fundamentos de SQL bien sólidos?

Las transacciones son SQL avanzado. Para usarlas bien necesitas dominar las operaciones básicas: SELECT, INSERT, UPDATE, DELETE, claves foráneas y consultas. Comprueba dónde estás:

👉 Test: SQL Básico 👉 Test: SQL vs NoSQL 

¿Ya usabas transacciones en tus proyectos o era la primera vez que veías el concepto? ¿Cuál de las 4 propiedades ACID te parece más crítica: la atomicidad o la consistencia? Cuéntanos en los comentarios 👇 — respondemos todos. 🚀

Etiquetas: SQL ACID

¿Te ha gustado esta entrada?

Compártela con tus compañeros para que también sigan aprendiendo.

Comunidad y Comentarios

0 COMENTARIOS

No hay comentarios todavía. Sé el primero en compartir tu opinión.

Escribe tu opinión
Respondiendo a