Lidar com erros em transações
O tratamento estruturado de exceções usa a construção TRY/CATCH para testar erros e manipular erros. Ao usar o tratamento de exceções com transações, é importante colocar as palavras-chave COMMIT ou ROLLBACK no local correto em relação aos blocos TRY/CATCH.
Confirmar transações
Ao usar transações com tratamento de exceção estruturado, coloque a COMMIT TRANSACTION dentro do bloco TRY como no exemplo de código a seguir:
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
Transação de reversão
Quando usado com manipulação de exceção estruturada, coloque a ROLLBACK TRANSACTION dentro do bloco CATCH como no exemplo de código a seguir:
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 reverter uma transação ativa, use a função XACT_STATE. XACT_STATE retorna os seguintes valores:
| Valor de retorno | Significado |
|---|---|
| 1 | A solicitação atual tem uma transação de usuário ativa e confirmável. |
| 0 | Nenhuma transação ativa. |
| -1 | A solicitação atual tem uma transação de usuário ativa, mas ocorreu um erro que fez com que a transação fosse classificada como uma transação não confirmada. |
XACT_STATE pode ser usado antes do comando ROLLBACK, para verificar se a transação está ativa.
O código a seguir mostra a função XACT_STATE que está sendo usada dentro do bloco CATCH para que a transação só seja revertida se houver uma transação de usuário ativa.
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;