Hantera fel i transaktioner

Slutförd

Strukturerad undantagshantering använder TRY/CATCH-konstruktionen för att testa fel och hantera fel. När du använder undantagshantering med transaktioner är det viktigt att placera nyckelorden COMMIT eller ROLLBACK på rätt plats i förhållande till TRY/CATCH-blocken.

Bekräfta transaktioner

När du använder transaktioner med strukturerad undantagshantering placerar du COMMIT TRANSACTION i TRY-blocket som i följande kodexempel:

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 

Återställ transaktion

När den används med strukturerad undantagshantering placerar du ROLLBACK-TRANSAKTIONEN i CATCH-blocket som i följande kodexempel:

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

Om du vill undvika att återställa en aktiv transaktion använder du funktionen XACT_STATE. XACT_STATE returnerar följande värden:

Returvärde Innebörd
1 Den nuvarande begäran har en aktiv, genomförbar användartransaktion.
0 Ingen aktiv transaktion.
-1 Den aktuella begäran har en aktiv användartransaktion, men ett fel har uppstått som har gjort att transaktionen klassificerats som en icke-bindande transaktion.

XACT_STATE kan användas före ROLLBACK-kommandot för att kontrollera om transaktionen är aktiv.

Följande kod visar den XACT_STATE funktion som används i CATCH-blocket så att transaktionen endast återställs om det finns en aktiv användartransaktion.

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;