首页 > 解决方案 > 为什么 T-SQL 在尝试截断列大小时会自动回滚事务?

问题描述

我有一个关于 T-SQL 行为的问题,但我找不到解释。

我设置了一个简单的表

create table SavedData (
    textData varchar(5)
)

当我运行以下 sql 时,插入了第一行

begin transaction
    insert into SavedData values (1, 'asd')
    insert into SavedData values (1, 'asdasdad') //exception here
commit transaction

但是当我运行这些时,没有插入任何行

begin transaction
    insert into SavedData values (1, 'asd')
    alter table SavedData alter column textData varchar(2) //exception here
commit transaction

在这两种情况下,都会在第二条语句中引发异常。但是为什么最后的结果不一样呢?

标签: sqlsql-servertsql

解决方案


如果您希望事务回滚,在第一个异常上,您需要将 XACT_ABORT 设置为 ON,请参见此处

设置 XACT_ABORT { 开 | 离开 }

指定当 Transact-SQL 语句引发运行时错误时 SQL Server 是否自动回滚当前事务。

如果您有 XACT_ABORT OFF(这是默认设置),则不能保证整个事务将被回滚:

当 SET XACT_ABORT 为 ON 时,如果 Transact-SQL 语句引发运行时错误,则整个事务将终止并回滚。

当 SET XACT_ABORT 为 OFF 时,在某些情况下,只有引发错误的 Transact-SQL 语句被回滚,事务继续处理。根据错误的严重程度,即使 SET XACT_ABORT 为 OFF,也可能回滚整个事务。关闭是默认设置。


推荐阅读