Obsługa błędów w transakcjach
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;