Нужно ли использовать блок try..catch и явный откат в процедуре SQL Server?

Если я кодирую процедуру SQL Server (2008r2) и заключаю ее в транзакцию, нужно ли явно заключить ее в блок try..catch, а затем явно вызвать откат в блоке catch или он завершится и откатить же самостоятельно?

т.е .:

Как это:

    begin transaction

    begin try
    delete from....

    insert into...
    end try
    begin catch
    rollback transaction
    return
    end catch

    commit transaction

Сравнить с:

    begin transaction
    delete from....

    insert into...
    commit transaction

Спасибо за любую помощь.

Ответы на вопрос(3)

Решение Вопроса

SET XACT_ABORT установка:

Specifies whether SQL Server automatically rolls back the current transaction when a Transact-SQL statement raises a run-time error.

When SET XACT_ABORT is ON, if a Transact-SQL statement raises a run-time error, the entire transaction is terminated and rolled back.

When SET XACT_ABORT is OFF, in some cases only the Transact-SQL statement that raised the error is rolled back and the transaction continues processing. Depending upon the severity of the error, the entire transaction may be rolled back even when SET XACT_ABORT is OFF. OFF is the default setting.

Compile errors, such as syntax errors, are not affected by SET XACT_ABORT.

Например, попробуйте следующий код. Первое деление на 0 вызывает ошибку, ноcontinues execution, Второе деление на ноль вызывает ошибку, которая останавливает выполнение:

begin transaction

set xact_abort off

select 1 / 0 -- causes divide by zero error, but continues
select @@trancount -- returns 1

set xact_abort on

select 1 / 0 -- causes divide by zero error and terminates execution
select @@trancount -- we never get here

rollback

Если XACT_ABORT установлен в положение ON, ошибки прервут транзакцию, и вам не понадобится TRY / CATCH.

Если XACT_ABORT выключен, вам нужно проверить состояние каждого оператора, чтобы увидеть, произошла ли ошибка:

begin transaction

delete from...
if @@error <> 0
begin
    if @@trancount > 0
        rollback
    return
end

insert into...
if @@error <> 0
begin
    if @@trancount > 0
        rollback
    return
end

commit

Тем не менее, если вы когда-нибудь найдете случай, когда вам нужно TRY / CATCH, вам может потребоваться сделать что-то особенное при возникновении ошибки. Если это так, не забудьте попробовать / обработать обработку исключений:

begin transaction

set xact_abort on

begin try
    select 1 / 0 -- causes divide by zero error and terminates execution
    select @@trancount -- we never get here
    commit
end try
begin catch
    select xact_state() -- this will be -1 indicating you MUST rollback before doing any other operations
    select @@trancount -- this will probably be one, because we haven't ended the transaction yet
    if xact_state() <> 0
    begin try
        select 'rollback'
        rollback

        -- do something to handle or record the error before leaving the current scope
        select 'exception processing here'
        --insert into...
    end try
    begin catch
        -- ignore rollback errors
    end catch

end catch

если в большинстве случаев возникает ошибка, но не все

если вы хотите гарантировать откат всех ошибок, предшествующих началу транзакции, с помощью SET XACT_ABORT ON

Лучшая практика состоит в том, чтобы подробно описывать ошибки с помощью блока try-catch и предпринимать там действия, в том числе, возможно, откат и сообщение об ошибке.

возможно? - процесс может остановиться на ошибочной линии, оставив транзакциюopen и ваши замки на месте. Если есть вероятность ошибки в транзакции, вы определенно хотите обернуть ее в блок try-catch, как вы это делали в первом примере.

Ваш ответ на вопрос