Я б скоріше порекомендував такий зразок, як обраний з обробки обміну винятком та вкладених транзакцій :
create procedure [usp_my_procedure_name]
as
begin
set nocount on;
declare @trancount int;
set @trancount = @@trancount;
begin try
if @trancount = 0
begin transaction
else
save transaction usp_my_procedure_name;
-- Do the actual work here
lbexit:
if @trancount = 0
commit;
end try
begin catch
declare @error int, @message varchar(4000), @xstate int;
select @error = ERROR_NUMBER(), @message = ERROR_MESSAGE(), @xstate = XACT_STATE();
if @xstate = -1
rollback;
if @xstate = 1 and @trancount = 0
rollback
if @xstate = 1 and @trancount > 0
rollback transaction usp_my_procedure_name;
raiserror ('usp_my_procedure_name: %d: %s', 16, 1, @error, @message) ;
end catch
end
Цей зразок перевіряє XACT_STATE()
вхідний блок для захисту від нерозбірливих транзакцій :
Непередавані транзакції та XACT_STATE
Якщо помилка, сформована в блоці TRY, призводить до визнання недійсним стану поточної транзакції, транзакція класифікується як транзакція, що не перебуває у стані розслідування. Помилка, яка зазвичай закінчує транзакцію поза блоком TRY, призводить до того, що транзакція переходить у нерозбірливий стан, коли помилка виникає всередині блоку TRY. Нездійсненна транзакція може виконувати лише операції з читання або ПЕРЕГЛЯДУВАННЯ ПОВЕРНЕННЯ. Транзакція не може виконати жодних операторів Transact-SQL, які б генерували операцію запису або ЗВ'ЯЗУЮТЬ ПЕРЕКЛАД. Функція XACT_STATE повертає значення -1, якщо транзакція була класифікована як непередавана транзакція. Коли пакет закінчується, Database Engine скасовує будь-які активні нерозбірливі транзакції. Якщо жодного повідомлення про помилку не було надіслано, коли транзакція перейшла в нерозбірливий стан, коли пакет закінчується, клієнтській програмі буде надіслано повідомлення про помилку. Це вказує на те, що невмируща транзакція була виявлена та повернута назад.
Ваш код перевіряється @@TRANCOUNT
в місцях, де його не може бути 0, він використовує суміш інформаційних повідомлень PRINT та набір результатів SELECT для успішного спілкування, він не обробляє помилки, які підлягають відшкодуванню. В ідеалі винятки повинні поширюватися на клієнта, в цьому випадку на роботу з агентом (тобто ваш улов повинен повторно збільшитися).