Отворете транзакция само след като сте вътре в TRY
block и точно преди действителното изявление и го завържете веднага. Не чакайте контрола ви да премине към края на партидата, за да извършите транзакциите си.
Ако нещо се обърка, докато сте в TRY
блокирате и сте отворили транзакция, контролата ще премине към CATCH
блок. Просто отменете транзакцията си там и направете друга обработка на грешки, ако е необходимо.
Добавих малка проверка за всяка отворена транзакция с помощта на @@TRANCOUNT
функция преди действително връщане назад на транзакцията. Всъщност няма много смисъл в този сценарий. По-полезно е, когато правите някои проверки за валидиране във вашия TRY
блокирайте, преди да отворите транзакция, като проверка на стойностите на параметрите и други неща и издигане на грешка в TRY
блокирайте, ако някоя от проверките за валидиране е неуспешна. В този случай контролата ще премине към CATCH
блокирайте, без дори да отворите транзакция. Там можете да проверите за всяка отворена транзакция и да върнете обратно, ако има отворени. Във вашия случай наистина не е нужно да проверявате за отворена транзакция, тъй като няма да въведете CATCH
блокирайте, освен ако нещо не се обърка във вашата транзакция.
Не питайте, след като сте изпълнили DELETE
операцията дали трябва да бъде ангажирана или връщана назад; направете всички тези проверки преди отваряне на транзакцията. След като транзакцията бъде отворена, завършете я незабавно и в случай на грешки, направете обработка на грешки (вършите добра работа, като получавате подробна информация, като използвате почти всички функции за грешки).
BEGIN TRY
BEGIN TRANSACTION SCHEDULEDELETE
DELETE -- delete commands full SQL cut out
DELETE -- delete commands full SQL cut out
DELETE -- delete commands full SQL cut out
COMMIT TRANSACTION SCHEDULEDELETE
PRINT 'X rows deleted. Operation Successful Tara.' --calculation cut out.
END TRY
BEGIN CATCH
IF (@@TRANCOUNT > 0)
BEGIN
ROLLBACK TRANSACTION SCHEDULEDELETE
PRINT 'Error detected, all changes reversed'
END
SELECT
ERROR_NUMBER() AS ErrorNumber,
ERROR_SEVERITY() AS ErrorSeverity,
ERROR_STATE() AS ErrorState,
ERROR_PROCEDURE() AS ErrorProcedure,
ERROR_LINE() AS ErrorLine,
ERROR_MESSAGE() AS ErrorMessage
END CATCH