Lidar com erros em transações
O tratamento de exceção estruturado usa o constructo TRY/CATCH para testar erros e manipular erros. Ao usar o tratamento de exceções com transações, é importante colocar as palavras-chave ou ROLLBACK palavras-chave COMMIT no lugar correto em relação aos blocos TRY/CATCH.
Confirmar transações
Ao usar transações com tratamento de exceção estruturado, coloque o COMMIT TRANSACTION bloco TRY dentro 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
Reverter transação
Quando usado com o tratamento de exceção estruturado, coloque o ROLLBACK TRANSACTION bloco CATCH dentro 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 XACT_STATE função.
XACT_STATE retorna os seguintes valores:
| Valor de retorno | Significado |
|---|---|
| 1 | A sessão atual tem uma transação de usuário ativa. A sessão pode executar qualquer ação, incluindo gravar dados e confirmar a transação. |
| 0 | Nenhuma transação ativa. |
| -1 | A sessão atual tem uma transação de usuário ativa, mas ocorreu um erro que classificou a transaçãocomol. A sessão não pode confirmar ou reverter para um ponto de salvamento; ele só pode executar leituras e deve emitir um .ROLLBACK TRANSACTION |
XACT_STATE pode ser usado antes do ROLLBACK comando, para verificar se a transação está ativa.
O código a seguir mostra a XACT_STATE função usada dentro de um bloco CATCH. Ele distingue o estado -1 (não confiável — deve reverter totalmente) do estado 1 (committable— pode ser confirmado):
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;
-- Test for uncommittable transaction (for example, caused by SET XACT_ABORT ON).
IF XACT_STATE() = -1
BEGIN
ROLLBACK TRANSACTION;
END;
-- Test for active, committable transaction.
IF XACT_STATE() = 1
BEGIN
COMMIT TRANSACTION;
END;
-- If XACT_STATE() = 0, there is no active transaction; no action needed.
END CATCH;