Control de errores en las transacciones

Completado

El control de excepciones estructurado usa la construcción TRY/CATCH para probar los errores y controlar los errores. Al usar el control de excepciones con transacciones, es importante colocar las palabras clave COMMIT o ROLLBACK en el lugar correcto en relación con los bloques TRY/CATCH.

Ejecutar transacciones

Al usar transacciones con control de excepciones estructurados, coloque COMMIT TRANSACTION dentro del bloque TRY como en el ejemplo de código siguiente:

BEGIN TRY
 BEGIN TRANSACTION
 	INSERT INTO dbo.Orders(custid, empid, orderdate)
	VALUES (68,9,'2006-07-12');
	INSERT INTO dbo.OrderDetails(orderid,productid,unitprice,qty)
	VALUES (1, 2,15.20,20);
 COMMIT TRANSACTION
END TRY 

Anulación de transacción

Cuando se usa con el control de excepciones estructurado, coloque ROLLBACK TRANSACTION dentro del bloque CATCH como en el ejemplo de código siguiente:

BEGIN TRY
 BEGIN TRANSACTION;
 	INSERT INTO dbo.Orders(custid, empid, orderdate)
	VALUES (68,9,'2006-07-12');
	INSERT INTO dbo.OrderDetails(orderid,productid,unitprice,qty)
	VALUES (1, 2,15.20,20);
 COMMIT TRANSACTION;
END TRY
BEGIN CATCH
	SELECT ERROR_NUMBER() AS ErrNum, ERROR_MESSAGE() AS ErrMsg;
	ROLLBACK TRANSACTION;
END CATCH;

XACT_STATE

Para evitar revertir una transacción activa, use la función XACT_STATE. XACT_STATE devuelve los siguientes valores:

Valor devuelto Significado
1 La solicitud actual tiene una transacción de usuario activa y confirmable.
0 No hay ninguna transacción activa.
-1 La solicitud actual tiene una transacción de usuario activa, pero se ha producido un error que ha provocado que la transacción se clasifique como una transacción no confirmable.

XACT_STATE se puede usar antes del comando ROLLBACK para comprobar si la transacción está activa.

El código siguiente muestra la función XACT_STATE que se usa en el bloque CATCH para que la transacción solo se revierte si hay una transacción de usuario activa.

BEGIN TRY
 BEGIN TRANSACTION;
 	INSERT INTO dbo.SimpleOrders(custid, empid, orderdate) 
	VALUES (68,9,'2006-07-12');
	INSERT INTO dbo.SimpleOrderDetails(orderid,productid,unitprice,qty) 
	VALUES (1, 2,15.20,20);
 COMMIT TRANSACTION;
END TRY
BEGIN CATCH
	SELECT ERROR_NUMBER() AS ErrNum, ERROR_MESSAGE() AS ErrMsg;
	IF (XACT_STATE()) <> 0
    	BEGIN
        ROLLBACK TRANSACTION;
    	END;
	ELSE .... -- provide for other outcomes of XACT_STATE()
END CATCH;