Skip to content

Transacciones

Una transacción es un conjunto de operaciones que se ejecutan como un bloque indivisible:
👉 Si una falla, fallan todas.
👉 Si todas tienen éxito, se confirman permanentemente.

Por defecto, SQL Server trabaja con transacciones de confirmación automática, es decir, cada instrucción es una transacción independiente y se confirma automáticamente.


En este caso, cada sentencia se confirma de forma automática, lo que puede generar inconsistencias si una instrucción falla.

DECLARE @importe DECIMAL(18,2),
@CuentaOrigen VARCHAR(12),
@CuentaDestino VARCHAR(12)
SET @importe = 50
SET @CuentaOrigen = '200700000001'
SET @CuentaDestino = '200700000002'
UPDATE CUENTAS
SET SALDO = SALDO - @importe
WHERE NUMCUENTA = @CuentaOrigen
INSERT INTO MOVIMIENTOS
(IDCUENTA, SALDO_ANTERIOR, SALDO_POSTERIOR, IMPORTE, FXMOVIMIENTO)
SELECT IDCUENTA, SALDO + @importe, SALDO, @importe, getdate()
FROM CUENTAS
WHERE NUMCUENTA = @CuentaOrigen
UPDATE CUENTAS
SET SALDO = SALDO + @importe
WHERE NUMCUENTA = @CuentaDestino
INSERT INTO MOVIMIENTOS
(IDCUENTA, SALDO_ANTERIOR, SALDO_POSTERIOR, IMPORTE, FXMOVIMIENTO)
SELECT IDCUENTA, SALDO - @importe, SALDO, @importe, getdate()
FROM CUENTAS
WHERE NUMCUENTA = @CuentaDestino

  • Explícitas → Inician con BEGIN TRANSACTION y finalizan con COMMIT o ROLLBACK.
  • Implícitas → Se inician automáticamente al ejecutar instrucciones de modificación, pero deben cerrarse con COMMIT o ROLLBACK.

Activar o desactivar transacciones implícitas

Section titled “Activar o desactivar transacciones implícitas”
-- Activar
SET IMPLICIT_TRANSACTIONS ON
-- Desactivar
SET IMPLICIT_TRANSACTIONS OFF

DECLARE @importe DECIMAL(18,2),
@CuentaOrigen VARCHAR(12),
@CuentaDestino VARCHAR(12)
SET @importe = 50
SET @CuentaOrigen = '200700000002'
SET @CuentaDestino = '200700000001'
BEGIN TRANSACTION
BEGIN TRY
UPDATE CUENTAS
SET SALDO = SALDO - @importe
WHERE NUMCUENTA = @CuentaOrigen
INSERT INTO MOVIMIENTOS
(IDCUENTA, SALDO_ANTERIOR, SALDO_POSTERIOR, IMPORTE, FXMOVIMIENTO)
SELECT IDCUENTA, SALDO + @importe, SALDO, @importe, getdate()
FROM CUENTAS
WHERE NUMCUENTA = @CuentaOrigen
UPDATE CUENTAS
SET SALDO = SALDO + @importe
WHERE NUMCUENTA = @CuentaDestino
INSERT INTO MOVIMIENTOS
(IDCUENTA, SALDO_ANTERIOR, SALDO_POSTERIOR, IMPORTE, FXMOVIMIENTO)
SELECT IDCUENTA, SALDO - @importe, SALDO, @importe, getdate()
FROM CUENTAS
WHERE NUMCUENTA = @CuentaDestino
COMMIT TRANSACTION
END TRY
BEGIN CATCH
ROLLBACK TRANSACTION
PRINT 'Se ha producido un error!'
END CATCH

  • COMMIT → Confirma los cambios de la transacción y los hace permanentes.
  • ROLLBACK → Revierte los cambios y devuelve la base de datos al estado inicial antes de la transacción.

Advertencia

Si una transacción no tiene un COMMIT, quedará abierta en segundo plano y bloqueará consultas sobre la tabla.


Podemos abrir varias transacciones dentro de otra.
👉 COMMIT solo afecta a la transacción actual.
👉 ROLLBACK afecta a todas las transacciones abiertas.

BEGIN TRAN
UPDATE EMPLEADOS
SET NOMBRE = 'Jaime'
WHERE ID = 101
BEGIN TRAN
UPDATE EMPLEADOS
SET APELLIDO1 = 'Pardo'
WHERE ID = 101
COMMIT -- Solo confirma la segunda transacción
ROLLBACK -- Revierte ambas transacciones

Los savepoints permiten marcar un punto dentro de la transacción al que podemos volver con ROLLBACK.

BEGIN TRAN
UPDATE CUENTAS
SET SALDO = 1
WHERE IDCUENTA = 1
UPDATE CUENTAS
SET SALDO = 2
WHERE IDCUENTA = 2
SAVE TRANSACTION P1
UPDATE CUENTAS
SET SALDO = 3
WHERE IDCUENTA = 3
ROLLBACK TRANSACTION P1 -- Revierte solo cambios posteriores a P1
COMMIT

Nota

ROLLBACK no retrocede la ejecución, simplemente deshace los cambios.
Con savepoints, solo se revierten las operaciones posteriores al punto marcado.