T-SQL回滚是确定性还是垃圾回收?

时间:2014-06-27 20:19:24

标签: sql sql-server tsql stored-procedures transactions

在我们的Miscrosoft Sql Server 2008数据库中,我发现了一些存储过程:

BEGIN TRY
    BEGIN TRANSACTION
        query1
        query2
        query3
    COMMIT TRANSACTION
END TRY

BEGIN CATCH
    ROLLBACK TRANSACTION
    RAISERROR
END CATCH

我对我的同事说,这在功能上与此相同:

BEGIN TRANSACTION
    query1
    query2
    query3
COMMIT TRANSACTION

如果,query2失败,你永远不会点击COMMIT行,所以当然SqlServer回滚,并且由于错误,它也会将它返回给客户端。由于CATCH块与默认值相同,我认为我们根本不需要TRY/CATCH块。

我的同事同意ROLLBACK最终会发生,但可能会在一段时间之后发生,并且可能会在一段非确定的时间内保留资源或锁定记录,这可能会导致问题。< / p>

所以我的问题是:如果存储过程在事务中失败,该事务何时回滚?

2 个答案:

答案 0 :(得分:3)

回滚不会以预期的方式触发您的解决方案。 你必须添加

set xact_abort on

查询。

有关详细信息,请参阅an old answerMicrosoft documentation

答案 1 :(得分:1)

只要客户端连接保持打开状态,SQL Server就会乐意将事务永久保持打开状态。显式回滚是一种很好的做法,因为它不会等待客户端连接物理关闭或池连接重用。 CATCH块中的简单THROW(SQL 2012及更高版本)将回滚事务并引发错误。

我建议使用SET XACT_ABORT ON选项哈希来缓解另一个问题。如果在查询执行期间发生客户端超时,则批处理中的其他代码(包括ROLLBACK)将不会执行,并且事务将保持打开状态。但是,事务仍将通过SET XACT_ABORT ON回滚。