GO命令在事务中的奇怪行为

时间:2016-06-14 18:15:01

标签: sql sql-server

如果我运行以下内容:

CREATE TABLE t1  
    (a INT NOT NULL PRIMARY KEY);  
CREATE TABLE t2  
    (a INT NOT NULL REFERENCES t1(a));  

INSERT INTO t1 VALUES (1);  
INSERT INTO t1 VALUES (3);  
INSERT INTO t1 VALUES (4);  
INSERT INTO t1 VALUES (6);  
GO  

之后我运行了这个:

SET XACT_ABORT ON; 

BEGIN TRANSACTION
INSERT INTO t2 VALUES (1)

INSERT INTO t2 VALUES (2) -- Foreign key error, entire transaction rolled back

INSERT INTO t2 VALUES (3)

COMMIT TRANSACTION

然后一切都好;事务被回滚,因为我们在t1中没有值2,因此表t2为空

但是如果我在此事务中间添加GO命令,则事务不会回滚,并且数字3将插入到表t2中。这是代码:

SET XACT_ABORT ON; 

BEGIN TRANSACTION
INSERT INTO t2 VALUES (1)

INSERT INTO t2 VALUES (2) -- Foreign key error.  

GO  --this command breaks the transaction

INSERT INTO t2 VALUES (3)

COMMIT TRANSACTION

我知道GO不是sql语句,而是实际上没有发送到SQL服务器的SQL Server Management Studio实用程序命令。

那么,为什么在运行上面的最后一个代码片段(包含GO命令的代码片段)后,我可以看到表t2中的数字3

我使用的是SQL Server Management Studio

1 个答案:

答案 0 :(得分:8)

  

http://docs.scipy.org/doc/scipy-0.14.0/reference/generated/scipy.spatial.KDTree.htmlON时,如果Transact-SQL语句引发了   运行时错误,整个事务终止并回滚。

第一批中打开的事务会在出错时自动回滚。

然后SSMS发现还有另一批要处理并触发

INSERT INTO t2 VALUES (3)

COMMIT TRANSACTION

当第一个事务现在关闭时,这将启动一个新的自动提交事务。最后有一个意外的COMMIT TRANSACTION因此会引发错误。

您可以更改第二批,以检查第一批中的交易是否被毫不客气地回滚。

SET XACT_ABORT ON; 

BEGIN TRANSACTION
INSERT INTO t2 VALUES (1)

INSERT INTO t2 VALUES (2) -- Foreign key error.  

GO 

IF @@TRANCOUNT = 0
    BEGIN
    RAISERROR('Transaction closed',16,1);
    RETURN;
    END

INSERT INTO t2 VALUES (3)

COMMIT TRANSACTION

或者您可以打开SQLCMD模式并使用

:on error exit

如果您希望在发生错误后不再处理其他批次。

SET XACT_ABORT