Transacciones en Transact SQL
Una transacción puede definirse como un conjunto de instrucciones que funcionan como una unidad, donde si una parte falla, todo el proceso falla en su totalidad, revirtiéndose todos los cambios producidos en la base de datos.
Para declarar una transacción partimos de la siguiente sintaxis:
BEGIN TRANSACTION
También será válida la sentencia acortada:
BEGIN TRAN
Una transacción, por tanto, valida todas las instrucciones que contiene como un único conjunto o unidad única de trabajo. Si todas las instrucciones funcionan, los cambios sobre la base de datos se confirman haciéndose permanentes. Si cualquier instrucción falla, todos los cambios deben revertirse.
A menudo y por tanto, es muy común que las transacciones contengan internamente estructuras de gestión de errores como TRY...CATH
, para confirmar o revertir los cambios en base de datos. Si el código falla, se capturará el error en el CATCH
y procederemos a revertir todos los cambios sobre la base de datos. Si todas las instrucciones del TRY
funcionan correctamente, se procederá a guardar los cambios.
Si desea más información respectiva al control y manejo de errores, visitar la sección gestión de errores.
El control de guardado y revertimiento de los cambios respectivamente, se realizará a través de las siguientes instrucciones:
-
COMMIT TRANSACTION: Confirma y hace permanentes los cambios de base de datos si la transacción finaliza correctamente.
-
ROLLBACK TRANSACTION: Deshace y revierte los cambios de una transacción cuando se produce un error durante la misma, hasta el inicio de la transacción o hasta un punto de retorno dentro de ella.
-
SAVE TRANSACTION: Establece un punto de guardado dentro de una transacción.
Para entender bien el funcionamiento de una transacción y los conceptos de COMMIT
y ROLLBACK
, supongamos que queremos añadir dos nuevos clientes
dentro de una transacción:
BEGIN TRANSACTION;
INSERT INTO Clientes VALUES ('Jesús',
'Nogales Calvo',
'Av. Manoteras 44',
NULL);
INSERT INTO Clientes VALUES ('Nuria',
NULL,
'Calle del sueño 98',
NULL);
COMMIT TRANSACTION;
Si ejecutamos el código de arriba, vemos que nos devuelve el siguiente mensaje de error:
No se puede insertar el valor NULL en la columna ‘apellidos’, tabla ‘tienda.dbo.Clientes’. La columna no admite valores NULL. Error de INSERT.
Sin embargo, si consultamos nuestra tabla Clientes
podemos ver que ha insertado correctamente el primer registro referente a: Jesús Nogales Calvo:
idClientes | nombre | apellidos | direccion | cuenta |
---|---|---|---|---|
1019 | Jesús | Nogales Calvo | Av. Manoteras 44 | NULL |
De este ejemplo, deducimos que no estamos haciendo un buen uso de la transacción, ya que no estamos contemplando los errores para deshacer los cambios con la instrucción ROLLBACK
.
En el siguiente ejemplo, vamos a contemplar una gestión de errores y la instrucción ROLLBACK
, para que en caso de que falle la inserción de un registro, falle el proceso en su totalidad.
BEGIN TRAN;
BEGIN TRY
INSERT INTO Clientes VALUES ('Alfonso',
'Gutierrez Lan',
'Av. Grande 23',
NULL);
INSERT INTO Clientes VALUES ('Nuria',
NULL,
'Calle del sueño 98',
NULL);
COMMIT TRAN;
END TRY
BEGIN CATCH
SELECT
ERROR_NUMBER() AS ErrorNumber
,ERROR_SEVERITY() AS ErrorSeverity
,ERROR_STATE() AS ErrorState
,ERROR_PROCEDURE() AS ErrorProcedure
,ERROR_LINE() AS ErrorLine
,ERROR_MESSAGE() AS ErrorMessage;
ROLLBACK TRAN
END CATCH;
ErrorNumber | ErrorSeverity | ErrorState | ErrorProcedure | ErrorLine | ErrorMessage |
---|---|---|---|---|---|
515 | 16 | 2 | NULL | 4 | No se puede insertar el valor NULL en la columna ‘apellidos’, tabla ‘tienda.dbo.Clientes’. La columna no admite valores NULL. Error de INSERT.. |
En este caso, aunque el primer INSERT INTO
del registro: Alfonso Gutierrez Lan funcione correctamente, al fallar el segundo, capturamos el error en el CATCH
y hacemos ROLLBACK
de la transacción. Por tanto, si consultamos la tabla Clientes
podemos comprobar que no se ha insertado ningún registro.