Confrontare transazioni e lotti

Completato

È utile confrontare il comportamento dei batch T-SQL, racchiusi all'interno di un blocco TRY/CATCH, con il comportamento delle transazioni.

Si consideri il codice seguente che inserisce due ordini cliente, che richiedono una riga nella tabella SalesLT.SalesOrderHeader e una o più righe nella tabella SalesLT.SalesOrderDetail . Tutte le istruzioni INSERT sono racchiuse all'interno del blocco TRY.

  • Se il primo inserimento ha esito negativo, l'esecuzione passa al blocco CATCH e non viene eseguito altro codice.
  • Se il secondo inserimento ha esito negativo, l'esecuzione passa al blocco CATCH e non viene eseguito altro codice. Tuttavia, il primo inserimento ha avuto esito positivo e non è stato eseguito il rollback, lasciando così il database in uno stato incoerente. È stata inserita una riga per l'ordine, ma nessuna riga per il dettaglio dell'ordine.
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;

Confrontarlo con l'implementazione del codice all'interno di una transazione. Il blocco TRY/CATCH viene ancora usato per la gestione degli errori, ma le istruzioni INSERT per le tabelle Orders e OrderDetails sono racchiuse tra le parole chiave BEGIN TRANSACTION/COMMIT TRANSACTION. In questo modo tutte le dichiarazioni vengono considerate come una singola transazione, che riesce o fallisce. Una riga viene scritta sia nella tabella Orders che in OrderDetails oppure nessuna delle due righe viene inserita. In questo modo, il database non può mai essere in uno stato incoerente.

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;