Sammenlign transaktioner og batches
Det er nyttigt at sammenligne funktionsmåden for T-SQL-batches, der er omsluttet af en TRY/CATCH-blok, med transaktionernes funktionsmåde.
Overvej følgende kode, der indsætter to kundeordrer, som kræver en række i tabellen SalesLT.SalesOrderHeader og en eller flere rækker i tabellen SalesLT.SalesOrderDetail . Alle INSERT-sætningerne er omsluttet af TRY-blokken.
- Hvis den første indsættelse mislykkes, overføres udførelsen til CATCH-blokken, og der udføres ingen yderligere kode.
- Hvis den anden indsættelse mislykkes, overføres udførelsen til CATCH-blokken, og der udføres ingen yderligere kode. Den første indsættelse blev dog udført og annulleres ikke, så databasen er i en inkonsistent tilstand. Der blev indsat en række for rækkefølgen, men ingen række for ordredetaljerne.
BEGIN TRY
INSERT INTO dbo.Orders(custid, empid, orderdate)
VALUES (68, 9, '2021-07-12');
INSERT INTO dbo.Orders(custid, empid, orderdate)
VALUES (88, 3, '2021-07-15');
INSERT INTO dbo.OrderDetails(orderid,productid,unitprice,qty)
VALUES (1, 2, 15.20, 20);
INSERT INTO dbo.OrderDetails(orderid,productid,unitprice,qty)
VALUES (999, 77, 26.20, 15);
END TRY
BEGIN CATCH
SELECT ERROR_NUMBER() AS ErrNum, ERROR_MESSAGE() AS ErrMsg;
END CATCH;
Sammenlign dette med implementering af koden i en transaktion. TRY/CATCH-blokken bruges stadig til fejlhåndtering, men INSERT-sætningerne for tabellerne Orders og OrderDetails er omsluttet af nøgleordene BEGIN TRANSACTION/COMMIT TRANSACTION. Dette sikrer, at alle sætninger behandles som en enkelt transaktion, som enten lykkes eller mislykkes. Enten skrives én række til både tabellen Orders og OrderDetails, eller ingen af rækkerne indsættes. På denne måde kan databasen aldrig være i en inkonsistent tilstand.
BEGIN TRY
BEGIN TRANSACTION;
INSERT INTO dbo.Orders(custid, empid, orderdate)
VALUES (68,9,'2006-07-15');
INSERT INTO dbo.OrderDetails(orderid,productid,unitprice,qty)
VALUES (99, 2,15.20,20);
COMMIT TRANSACTION;
END TRY
BEGIN CATCH
SELECT ERROR_NUMBER() AS ErrNum, ERROR_MESSAGE() AS ErrMsg;
ROLLBACK TRANSACTION;
END CATCH;