您的问题的答案取决于SET XACT_ABORT
设置:
指定当 Transact-SQL 语句引发运行时错误时 SQL Server 是否自动回滚当前事务。
当 SET XACT_ABORT 为 ON 时,如果 Transact-SQL 语句引发运行时错误,则整个事务将终止并回滚。
当 SET XACT_ABORT 为 OFF 时,在某些情况下,只有引发错误的 Transact-SQL 语句被回滚并且事务继续处理。根据错误的严重程度,即使 SET XACT_ABORT 为 OFF,也可能回滚整个事务。
关闭是默认设置。
编译错误(例如语法错误)不受 SET XACT_ABORT 影响。
例如,试试下面的代码。第一次除以 0 会引发错误,但会继续执行。第二次除以零会引发错误并停止执行:
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 为 OFF,您将需要检查每个语句的状态以查看是否发生错误:
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