2012-07-10 72 views
6
USE AdventureWorks; 
GO 
BEGIN TRANSACTION; 
GO 
DELETE FROM HumanResources.JobCandidate WHERE JobCandidateID = 10; 
DELETE FROM HumanResources.JobCandidate WHERE JobCandidateID = 11; 
DELETE FROM HumanResources.JobCandidate WHERE JobCandidateID = 12; 
GO 
COMMIT TRANSACTION; 
GO 

如果第一个删除语句失败会发生什么?是否会执行第二个和第三个删除语句?该示例没有任何错误处理,如果发生异常,它会保留一个打开的事务,还是SQL Server会自动回滚事务?打开交易=锁定的资源,对吧?是否需要ROLLBACK TRANSACTION?

我决定是否必须将TRY ... CATCH应用于使用事务的存储过程。

我知道关于​​,但想知道没有它会发生什么。

以下是我在文档中发现 - 控制事务(数据库引擎):

如果某个错误阻止交易顺利完成,SQL Server会自动回滚事务,并释放该持有的所有资源交易

但是我在其他文章中读到自动回滚未被触发。

+0

是的,使用try ... catch。 – Ben 2012-07-10 13:40:46

回答

11

在你的榜样,而无需使用SET XACT_ABORT ON,交易将继续,甚至当第一语句失败提交。在你引用的文字中,关键词是if an error **prevents** the successful completion of a transaction,而DELETE陈述失败并不妨碍交易完成。

会导致自动回滚的错误的一个示例是,如果到事务中间的数据库连接被切断。再往下MSDN article你引用说:

如果运行时语句错误(如违反约束),在批处理时 ,在数据库引擎的默认行为是推出 回的只有声明产生了错误。您可以使用SET XACT_ABORT语句更改此行为 行为。执行SET XACT_ABORT ON 后,任何运行时语句错误都会导致当前事务的自动回滚 。编译错误,如语法错误, 不受SET XACT_ABORT的影响。

如果需要的话,使用错误处理来捕获错误和回滚总是一个好主意。

+0

因此,它会回滚失败的第一条删除语句,然后开始执行第二条语句,然后以同样的方式 - 第三条?最后会下降到提交声明?这意味着单个语句中的错误不会停止批处理执行,对吧? – 2012-07-10 14:06:19

+0

完全正确。此外,我更新了我的答案(希望)会更清楚一点:) – 2012-07-10 14:09:04

5

我喜欢手动控制过程:

BEGIN TRY 
BEGIN TRAN 

    -- do work 

COMMIT 
END TRY 
BEGIN CATCH 
    ROLLBACK 
    RAISERROR (...) 
END CATCH 
GO 
相关问题