SQL Server 2008事务,需要回滚吗?

TJF*_*TJF 7 t-sql sql-server transactions rollback

我有一个存储过程有一个BEGIN TRANSACTIONCOMMIT TRANSACTION语句.在事务内是一个选择查询WITH(XLOCK, ROWLOCK).

如果提供了超出边界值的某些计算导致算术溢出错误,则事务可能会失败.在任何插入/更新语句之前都会发生此错误.

我的问题是,我应该将事务包装在TRY/CATCH和回滚中,还是这不是真正需要的,如果事务失败,所有锁都会自动释放?我唯一担心的是,在事务失败的情况下,SQL不会释放事务的所有锁.

谢谢,

汤姆

And*_*mar 8

一种更简单的方法是:

set xact_abort on
Run Code Online (Sandbox Code Playgroud)

这将导致在发生错误时自动回滚事务.

示例代码:

set xact_abort on
begin transaction
select 1/0
go
print @@trancount -- Prints 0

set xact_abort off
begin transaction
select 1/0
go
print @@trancount -- Prints 1
Run Code Online (Sandbox Code Playgroud)

如果多次执行第二个段,您将看到事务计数增加到2,3,4等.第一个段的单个运行将重置所有事务.


Phi*_*ley 6

简短回答:是的.

每当我使用BEGIN TRANSACTION时,我总是包含使用错误处理和ROLLBACK.打一个意料之外的后果(和/或unanticipatable -你可以不知道你的代码怎么可能需要在未来进行修改),其在生产服务器上留下一个开放的交易情况太过严重到无法做到.

在SQL Server 2000及更早版本中,您必须使用@@ Error逻辑.在SQL 2005及更高版本中,您可以使用(远优于)TRY ... CATCH ...语法.


Ben*_*pka 5

我喜欢Brad的方法,但它需要一点点清理,以便您可以看到导致问题的错误.

begin try
    begin transaction;

    ...

    commit transaction;
end try
begin catch
    declare @ErrorMessage nvarchar(max), @ErrorSeverity int, @ErrorState int;
    select @ErrorMessage = ERROR_MESSAGE() + ' Line ' + cast(ERROR_LINE() as nvarchar(5)), @ErrorSeverity = ERROR_SEVERITY(), @ErrorState = ERROR_STATE();
    rollback transaction;
    raiserror (@ErrorMessage, @ErrorSeverity, @ErrorState);
end catch
Run Code Online (Sandbox Code Playgroud)