【问题标题】:Transactions Rolling Back by default when XACT_ABORT is offXACT_ABORT 关闭时事务默认回滚
【发布时间】:2018-03-08 10:26:01
【问题描述】:

我有以下交易

BEGIN TRAN
        DECLARE @TransactionAmount MONEY = 5.00
        UPDATE Account SET Balance -= @TransactionAmount WHERE AccountID = 1
        UPDATE Account SET Balance += @TransactionAmount WHERE AccountID = 'blah'
COMMIT TRAN

由于第二个UPDATE 语句失败(AccountID 是一个int 列)并且整个语句被包裹在一个TRAN 块中,所以第一个语句中的更改回滚并且余额对于 AccountID 1 没有扣除。

由于上面的代码中没有ROLLBACK 语句,SQL Server 似乎自动执行回滚而不需要显式的ROLLBACK 语句

当我查看它时,似乎自动回滚行为是由一个名为 xact_abort 的设置控制的。

我在网上找到了下面的脚本,它打印出打开的设置

DECLARE @options INT
SELECT @options = @@OPTIONS

PRINT @options
IF ( (1 & @options) = 1 ) PRINT 'DISABLE_DEF_CNST_CHK' 
IF ( (2 & @options) = 2 ) PRINT 'IMPLICIT_TRANSACTIONS' 
IF ( (4 & @options) = 4 ) PRINT 'CURSOR_CLOSE_ON_COMMIT' 
IF ( (8 & @options) = 8 ) PRINT 'ANSI_WARNINGS' 
IF ( (16 & @options) = 16 ) PRINT 'ANSI_PADDING' 
IF ( (32 & @options) = 32 ) PRINT 'ANSI_NULLS' 
IF ( (64 & @options) = 64 ) PRINT 'ARITHABORT' 
IF ( (128 & @options) = 128 ) PRINT 'ARITHIGNORE'
IF ( (256 & @options) = 256 ) PRINT 'QUOTED_IDENTIFIER' 
IF ( (512 & @options) = 512 ) PRINT 'NOCOUNT' 
IF ( (1024 & @options) = 1024 ) PRINT 'ANSI_NULL_DFLT_ON' 
IF ( (2048 & @options) = 2048 ) PRINT 'ANSI_NULL_DFLT_OFF' 
IF ( (4096 & @options) = 4096 ) PRINT 'CONCAT_NULL_YIELDS_NULL' 
IF ( (8192 & @options) = 8192 ) PRINT 'NUMERIC_ROUNDABORT' 
IF ( (16384 & @options) = 16384 ) PRINT 'XACT_ABORT'

但是,当在我的服务器上运行时,XACT_ABORT 没有出现在打印列表中,因此没有打开。

我的问题是:当 SQL Server 似乎在自动回滚时,还需要 ROLLBACK 语句吗?

【问题讨论】:

    标签: sql-server transactions sql-server-2014 xact-abort


    【解决方案1】:

    如果XACT_ABORT = OFF,那么事务是否回滚是非常不可预测的。 SQL Server 有时不会,有时会,有时甚至会中止批处理。 (是的,这没有任何意义。)其他可能的结果包括终止交易或切断连接。

    在您的情况下,您可以可靠地使用 TRY-CATCH 来防止回滚并处理异常。

    我发现尽可能不依赖错误处理是一个好习惯。相反,回滚事务。如果可能,还将错误处理推送到客户端。

    【讨论】:

      【解决方案2】:

      如果您使用事务,建议在存储过程开始时设置 XACT_ABORT = ON。 Erland Sommarskog 有一篇关于错误处理的优秀文章:

      http://www.sommarskog.se/error_handling/Part1.html

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2019-12-24
        • 2015-02-11
        • 1970-01-01
        • 1970-01-01
        • 2010-11-23
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多