在我们的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>
所以我的问题是:如果存储过程在事务中失败,该事务何时回滚?
答案 0 :(得分:3)
答案 1 :(得分:1)
只要客户端连接保持打开状态,SQL Server就会乐意将事务永久保持打开状态。显式回滚是一种很好的做法,因为它不会等待客户端连接物理关闭或池连接重用。 CATCH块中的简单THROW(SQL 2012及更高版本)将回滚事务并引发错误。
我建议使用SET XACT_ABORT ON选项哈希来缓解另一个问题。如果在查询执行期间发生客户端超时,则批处理中的其他代码(包括ROLLBACK)将不会执行,并且事务将保持打开状态。但是,事务仍将通过SET XACT_ABORT ON回滚。