Sql server SQL Server 2008事务,是否需要回滚?

Sql server SQL Server 2008事务,是否需要回滚?,sql-server,tsql,transactions,rollback,Sql Server,Tsql,Transactions,Rollback,我有一个存储过程,它有一个begintransaction和COMMIT TRANSACTION语句。事务中有一个选择查询,带有(XLOCK,ROWLOCK) 如果提供了超出边界的值,事务可能会由于某些计算而失败,从而导致算术溢出错误。此错误将在任何insert/update语句之前发生 我的问题是,我应该用TRY/CATCH-and-rollback来包装事务,还是这不是必需的,如果事务失败,所有锁都会自动释放?这里我唯一担心的是,如果事务失败,SQL不会释放事务的所有锁 谢谢 TomTRY/

我有一个存储过程,它有一个
begintransaction
COMMIT TRANSACTION
语句。事务中有一个选择查询
,带有(XLOCK,ROWLOCK)

如果提供了超出边界的值,事务可能会由于某些计算而失败,从而导致算术溢出错误。此错误将在任何insert/update语句之前发生

我的问题是,我应该用TRY/CATCH-and-rollback来包装事务,还是这不是必需的,如果事务失败,所有锁都会自动释放?这里我唯一担心的是,如果事务失败,SQL不会释放事务的所有锁

谢谢


Tom

TRY/CATCH
不需要释放锁。但是,我认为以下模板适用于大多数事务

BEGIN TRY
    BEGIN TRAN
    ...
    IF (@@error <> 0)
       ROLLBACK TRAN
END TRY
BEGIN CATCH
    ROLLBACK TRAN
END CATCH
--BEGIN FINALLY (doesnt exist, which is why I commented it out)    
    IF (@@trancount > 0)
       COMMIT TRAN
--END FINALLY
开始尝试
开始训练
...
如果(@@0错误)
回滚传输
结束尝试
开始捕捉
回滚传输
端接
--最后开始(不存在,这就是我将其注释掉的原因)
如果(@@trancount>0)
提交传输
--最后结束
简短回答:是

每当我使用BeginTransaction时,我总是包括使用错误处理和回滚。在生产服务器上留下打开的事务的意外情况(和/或意外情况——您不知道将来可能需要如何修改代码)的后果非常严重,不能不这样做

在SQL Server 2000及更早版本中,必须使用@错误逻辑。在SQL 2005及以上版本中,您可以使用(远远优于)TRY…CATCH。。。语法。

更简单的方法是:

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

示例代码:

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

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

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

BEGIN TRY
    BEGIN TRAN
    ...
    IF (@@error <> 0)
       ROLLBACK TRAN
END TRY
BEGIN CATCH
    ROLLBACK TRAN
END CATCH
--BEGIN FINALLY (doesnt exist, which is why I commented it out)    
    IF (@@trancount > 0)
       COMMIT TRAN
--END FINALLY
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