为什么 SQL 服务器默认 XACT_ABORT 为关闭?可以全局设置为ON吗?

Why does SQL Server default XACT_ABORT to OFF? Can it be set to ON globally?

我理解 SET XACT_ABORT 命令的目的:

When SET XACT_ABORT is ON, if a Transact-SQL statement raises a run-time error, the entire transaction is terminated and rolled back.

When SET XACT_ABORT is OFF, in some cases only the Transact-SQL statement that raised the error is rolled back and the transaction continues processing. Depending upon the severity of the error, the entire transaction may be rolled back even when SET XACT_ABORT is OFF. OFF is the default setting.

一般来说,发生错误时希望继续处理事务的情况要多于发生错误时希望回滚整个事务的情况,因为我经常听到 DBA 和博客建议保留 SET XACT_ABORT ON避免运行变成不一致的交易结果。我已经看到我们所有的存储过程也有 SET XACT_ABORT ON,作为模板代码的一部分。

问题:

  1. 如果大多数用例要求 XACT_ABORTON,什么会导致 SQL 服务器将其默认为 OFF?将 XACT_ABORT 默认为 ON 是否会增加 SQL 服务器事务处理的开销?

  2. SET XACT_ABORT 命令仅影响当前会话。我知道我可以将 SSMS 从 SSMS > Tools > Options > Query Execution > SQL Server > Advanced 默认设置为 SET XACT_ABORT ON,如下图所示: 但这仅限于通过 SSMS 的 SQL 语句 运行,对通过应用程序 code/SSIS 包调用的存储过程没有帮助。对于这些程序,我仍然必须在每个程序中重复 SET XACT_ABORT ON。有什么办法可以在数据库级别将 XACT_ABORT 设置为 ON 吗?还有其他方法可以全局设置 XACT_ABORT 而不必每次都担心吗?

您可以在服务器级别将 XACT_ABORT ON 设置为全局默认连接设置,尽管命令有点晦涩:

EXEC sys.sp_configure N'user options', N'16384'
GO
RECONFIGURE WITH OVERRIDE
GO

详情见here

也可以通过 SSMS 对象资源管理器 > 服务器属性 > 连接设置该选项: