Obsługa błędów w transakcjach

Ukończone

Obsługa wyjątków strukturalnych używa konstrukcji TRY/CATCH do testowania pod kątem błędów i obsługi błędów. W przypadku korzystania z obsługi wyjątków z transakcjami ważne jest umieszczenie słów kluczowych COMMIT lub ROLLBACK we właściwym miejscu w odniesieniu do bloków TRY/CATCH.

Zatwierdzanie transakcji

W przypadku korzystania z transakcji z obsługą wyjątków strukturalnych umieść transakcję COMMIT w bloku TRY, jak w poniższym przykładzie kodu:

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 

Cofnięcie transakcji

W przypadku użycia z obsługą wyjątków strukturalnych umieść komendę ROLLBACK TRANSACTION wewnątrz bloku CATCH, jak w poniższym przykładzie kodu:

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

Aby uniknąć wycofywania aktywnej transakcji, użyj funkcji XACT_STATE. XACT_STATE zwraca następujące wartości:

Wartość zwracana Znaczenie
1 Bieżące żądanie ma aktywną, zatwierdzaną transakcję użytkownika.
0 Brak aktywnej transakcji.
-1 Bieżące żądanie ma aktywną transakcję użytkownika, ale wystąpił błąd, który spowodował, że transakcja została sklasyfikowana jako transakcja nieuwierzytna.

XACT_STATE można użyć przed poleceniem ROLLBACK, aby sprawdzić, czy transakcja jest aktywna.

Poniższy kod przedstawia funkcję XACT_STATE używaną w bloku CATCH, tak aby transakcja została wycofana tylko wtedy, gdy istnieje aktywna transakcja użytkownika.

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;