Para implementar las propiedades ACID en Microsoft SQL Server (T-SQL), utilizaremos el escenario a las cuentas bancarias de la demostración en PostgreSQL, pero adaptado a la sintaxis nativa de Microsoft.
A diferencia de PostgreSQL, SQL Server requiere un manejo explícito de errores (TRY...CATCH) para asegurar la atomicidad y revertir los cambios de forma manual ante fallas de ejecución.
1. Diccionario y Estructura de Objetos de Base de Datos
Antes de ejecutar los scripts, detallamos los objetos que se crearán en la base de datos:
- Tabla
Cuentas: Almacena la información financiera de los clientes.Id (INT, IDENTITY(1,1)): Clave primaria autoincremental para identificar de forma única cada cuenta.Cliente (VARCHAR(50)): Nombre del titular de la cuenta. No permite valores nulos (NOT NULL).Saldo(DECIMAL(10, 2)): Almacena el dinero disponible con precisión decimal de dos dígitos. No permite valores nulos.
- Restricción
CK_Cuentas_Saldo_Positivo(CHECK): Regla de integridad a nivel de columna que impide que el campo Saldo sea menor a cero (Saldo >= 0). - Índice Clúster (
PK_Cuentas): Creado automáticamente con la clave primaria para optimizar la velocidad de búsqueda física en el disco.
Script de Inicialización:
-- 1. Crear la tabla con sus restricciones de integridad
CREATE TABLE Cuentas (
Id INT IDENTITY(1,1),
Cliente VARCHAR(50) NOT NULL,
Saldo DECIMAL(10, 2) NOT NULL,
-- Restricción de Consistencia
CONSTRAINT PK_Cuentas PRIMARY KEY CLUSTERED (Id),
CONSTRAINT CK_Cuentas_Saldo_Positivo CHECK (Saldo >= 0)
);
GO
-- 2. Insertar datos iniciales de prueba
INSERT INTO Cuentas (Cliente, Saldo)
VALUES ('Alicia', 500.00), ('Bruno', 100.00);
GO
2. Implementación y Ejemplos de los 4 Pilares en T-SQL
⚛️ Atomicidad (Atomicity)
En SQL Server, si ocurre un error de ejecución en medio de una transacción, las instrucciones previas pueden quedarse "en el limbo" a menos que uses XACT_ABORT ON o un bloque TRY...CATCH para forzar el ROLLBACK.
-- Habilita que cualquier error aborte la transacción inmediatamente
SET XACT_ABORT ON;
BEGIN TRANSACTION;
BEGIN TRY
-- Paso 1: Descontar saldo a Alicia
UPDATE Cuentas SET Saldo = Saldo - 100.00 WHERE Cliente = 'Alicia';
-- Paso 2: Forzar un error de ejecución (Dividir entre cero)
-- Esto simula una caída o un error lógico en la transferencia
SELECT 1 / 0;
-- Paso 3: Este paso nunca se ejecutará
UPDATE Cuentas SET Saldo = Saldo + 100.00 WHERE Cliente = 'Bruno';
-- Si todo sale bien, guarda los cambios
COMMIT TRANSACTION;
PRINT 'Transacción completada con éxito.';
END TRY
BEGIN CATCH
-- Si ocurre CUALQUIER error, se ejecuta este bloque y se revierte todo
IF @@TRANCOUNT > 0
BEGIN
ROLLBACK TRANSACTION;
PRINT 'Atomicidad Activada: Ocurrió un error. Se revirtieron todos los cambios.';
END
END CATCH;
GO
🛡️ Consistencia (Consistency)
La consistencia garantiza que la base de datos pase de un estado válido a otro estado válido. SQL Server utiliza la restricción CHECK para rechazar operaciones inválidas.
BEGIN TRANSACTION;
BEGIN TRY
-- Bruno intenta retirar $150.00, pero solo tiene $100.00
UPDATE Cuentas SET Saldo = Saldo - 150.00 WHERE Cliente = 'Bruno';
COMMIT TRANSACTION;
END TRY
BEGIN CATCH
-- El bloque CATCH captura la violación del CHECK CONSTRAINT
IF @@TRANCOUNT > 0 ROLLBACK TRANSACTION;
-- Mostrar detalle del error de consistencia
PRINT 'Error de Consistencia Detectado: ' + ERROR_MESSAGE();
END CATCH;
GO
🔒 Aislamiento (Isolation)
SQL Server utiliza bloqueos por defecto (READ COMMITTED). Para demostrar el aislamiento de forma clara, utilizaremos un nivel más estricto llamado SERIALIZABLE para evitar modificaciones externas mientras leemos datos.
- Sesión 1 (Usuario que consulta un reporte congelando los datos):
SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;
BEGIN TRANSACTION;
-- Lee los datos de Alicia. SQL Server coloca un bloqueo de lectura en esta fila.
SELECT * FROM Cuentas WHERE Cliente = 'Alicia';
-- NOTA: Mantenga esta transacción abierta (no ejecute COMMIT aún)
- Sesión 2 (Usuario concurrente intentando modificar los datos desde otra ventana):
-- Intenta modificar los datos bloqueados por la Sesión 1
UPDATE Cuentas SET Saldo = 600.00 WHERE Cliente = 'Alicia';
-- RESULTADO: La Sesión 2 se quedará congelada en estado de espera (Lock Wait)
-- hasta que la Sesión 1 ejecute COMMIT TRANSACTION o ROLLBACK TRANSACTION.
💾 Durabilidad (Durability)
Una vez que el motor de base de datos de SQL Server confirma un COMMIT, la transacción se escribe inmediatamente en el archivo de registro de transacciones físico (.ldf) en el disco duro antes de enviarle la respuesta exitosa a la aplicación.
BEGIN TRANSACTION;
UPDATE Cuentas SET Saldo = Saldo + 50.00 WHERE Cliente = 'Alicia';
COMMIT TRANSACTION;
GO
-- Explicación Técnica de Durabilidad:
-- En este punto exacto, el cambio ya se encuentra registrado en el Log de Transacciones (WAL).
-- Si el sistema operativo del servidor colapsa de forma abrupta o se corta la energía eléctrica,
-- el proceso de recuperación automática de SQL Server (Recovery Process) leerá el archivo .ldf
-- al reiniciar y aplicará ("Redo") este cambio para garantizar que el saldo de Alicia sea el correcto.
Lo recomendable es crear procedimiento almacenados y consumirlos desde una API con la finalidad de distribuir la solución.
0 Comentarios