השוואה בין טרנזקציות ואצוות
כדאי להשוות את אופן הפעולה של אצוות T-SQL, המוקפות בבלוק TRY/CATCH, לאו אופן הפעולה של טרנזקציות.
שקול את הקוד הבא שמוסיף שתי הזמנות של לקוחות, הדורש שורה בטבלה SalesLT.SalesOrderHeader ושורת אחת או יותר בטבלה SalesLT.SalesOrderDetail . כל משפטי INSERT מוקפים בבלוק TRY.
- אם ההוספה הראשונה נכשלת, הביצוע עובר לבלוק CATCH ולא מבוצע קוד נוסף.
- אם ההוספה השניה נכשלת, הביצוע עובר לבלוק CATCH ולא מבוצע קוד נוסף. עם זאת, ההוספה הראשונה הצליחה, והיא אינה חוזרת למצב קודם וונותחת ממסד הנתונים במצב לא עקבי. הוכנסה שורה עבור ההזמנה, אך לא שורה עבור פרטי ההזמנה.
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;
השווה זאת ליישום הקוד בתוך טרנזקציה. הבלוק TRY/CATCH עדיין משמש לטיפול בשגיאות, אולם משפטי INSERT עבור הטבלאות Orders ו- OrderDetails מוקפים במילות מפתח BEGIN TRANSACTION/COMMIT TRANSACTION. פעולה זו מבטיחה שכל המשפטים יטופלו כטרנזקציה יחידה, אשר מצליחה או נכשלת. שורה אחת נכתבת הן בטבלה Orders והן ב- OrderDetails, או שאף שורה אינה נוספת. בדרך זו, מסד הנתונים לעולם לא יוכל להיות במצב לא עקבי.
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;