至少在 SQL SERVER 2008 中,SET XACT_ABORT ON 不会导致跳过 CATCH 块的错误:
这是我尝试使用 Northwind 数据库的代码
SET XACT_ABORT OFF
BEGIN TRY
SELECT 1, @@TRANCOUNT
BEGIN TRAN
UPDATE [dbo].[Categories]
SET Description='BLAH'
WHERE [CategoryID]=2
SELECT 2, @@TRANCOUNT
SELECT 1/0 as whoops
COMMIT
SELECT 3, @@TRANCOUNT
END TRY
BEGIN CATCH
SELECT 'In Catch. Error occured', 4, @@TRANCOUNT
IF (XACT_STATE()) = 0
BEGIN
SELECT
N'There is no transaction'
END;
IF (XACT_STATE()) = -1
BEGIN
SELECT
N'The transaction is in an uncommittable state.' +
'Rolling back transaction.'
ROLLBACK TRANSACTION;
END;
-- Test whether the transaction is committable.
IF (XACT_STATE()) = 1
BEGIN
SELECT
N'The transaction is committable.' +
'Committing transaction.'
COMMIT TRANSACTION;
END;
END CATCH
显然,这将在遇到 SELECT 1/0 语句时强制出错。在 SET XACT_ABORT OFF 的情况下,当到达 CATCH 块时,XACT_STATE() 函数返回的值为 1,从而导致运行提交事务的代码。当 SET XACT_ABORT 开启时,在 CATCH 块中返回的值为 -1,因此执行回滚事务的代码。
这是基于:
http://msdn.microsoft.com/en-us/library/ms175976.aspx