Gérer les erreurs dans les transactions

Effectué

La gestion structurée des exceptions utilise la construction TRY/CATCH pour tester les erreurs et gérer les erreurs. Lorsque vous utilisez la gestion des exceptions avec des transactions, il est important de placer les mots clés COMMIT ou ROLLBACK au bon endroit par rapport aux blocs TRY/CATCH.

Valider les transactions

Lorsque vous utilisez des transactions avec gestion des exceptions structurées, placez LA TRANSACTION COMMIT à l’intérieur du bloc TRY comme dans l’exemple de code suivant :

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 

Annuler la transaction

Lorsqu’elle est utilisée avec la gestion des exceptions structurées, placez la TRANSACTION ROLLBACK à l’intérieur du bloc CATCH comme dans l’exemple de code suivant :

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

Pour éviter de restaurer une transaction active, utilisez la fonction XACT_STATE. XACT_STATE retourne les valeurs suivantes :

Valeur retournée Signification
1 La requête actuelle a une transaction utilisateur active et commitable.
0 Aucune transaction active.
-1 La requête actuelle a une transaction utilisateur active, mais une erreur s’est produite qui a provoqué la classification de la transaction comme une transaction noncommittable.

XACT_STATE pouvez être utilisé avant la commande ROLLBACK pour vérifier si la transaction est active.

Le code suivant montre la fonction XACT_STATE utilisée dans le bloc CATCH afin que la transaction soit restaurée uniquement s’il existe une transaction utilisateur active.

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;