Gestire gli errori nelle transazioni
La gestione strutturata delle eccezioni usa il costrutto TRY/CATCH per testare gli errori e gestire gli errori. Quando si usa la gestione delle eccezioni con le transazioni, è importante inserire le parole chiave COMMIT o ROLLBACK nella posizione corretta in relazione ai blocchi TRY/CATCH.
Transazioni commit
Quando si usano transazioni con gestione delle eccezioni strutturate, inserire COMMIT TRANSACTION all'interno del blocco TRY come nell'esempio di codice seguente:
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
Transazioni di rollback
Se usato con la gestione delle eccezioni strutturate, inserire ROLLBACK TRANSACTION all'interno del blocco CATCH come nell'esempio di codice seguente:
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
Per evitare il rollback di una transazione attiva, usare la funzione XACT_STATE. XACT_STATE restituisce i valori seguenti:
| Valore restituito | Significato |
|---|---|
| 1 | La richiesta corrente dispone di una transazione utente attiva e di cui è possibile eseguire il commit. |
| 0 | Nessuna transazione attiva. |
| -1 | La richiesta corrente ha una transazione utente attiva, ma si è verificato un errore che ha causato la classificazione della transazione come transazione non modificabile. |
XACT_STATE possibile usare prima del comando ROLLBACK per verificare se la transazione è attiva.
Il codice seguente mostra la funzione XACT_STATE utilizzata all'interno del blocco CATCH in modo che venga eseguito il rollback della transazione solo se è presente una transazione utente attiva.
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;