Sql server 发生错误时,为什么SQL Server事务会继续?

Sql server 发生错误时,为什么SQL Server事务会继续?,sql-server,tsql,transactions,Sql Server,Tsql,Transactions,我假设一个错误将中止事务,但事实并非如此。为什么在下面的代码中创建表t2 IF OBJECT_ID('dbo.t1', 'U') IS NOT NULL DROP TABLE dbo.t1 IF OBJECT_ID('dbo.t2', 'U') IS NOT NULL DROP TABLE dbo.t2 GO SELECT OBJECT_ID(N't1', N'U') AS t1_Exists, OBJECT_ID(N't2', N'U') AS t2

我假设一个错误将中止事务,但事实并非如此。为什么在下面的代码中创建表t2

IF OBJECT_ID('dbo.t1', 'U') IS NOT NULL 
    DROP TABLE dbo.t1

IF OBJECT_ID('dbo.t2', 'U') IS NOT NULL 
    DROP TABLE dbo.t2
GO

SELECT 
    OBJECT_ID(N't1', N'U') AS t1_Exists, 
    OBJECT_ID(N't2', N'U') AS t2_Exists
GO

BEGIN TRANSACTION 

CREATE TABLE t1 (id INT)
GO
CREATE TABLE t1 (id INT)--Causes an error, since t1 already exists
GO
CREATE TABLE t2 (id INT)
GO

COMMIT TRANSACTION 
GO

SELECT 
    OBJECT_ID(N't1', N'U') AS t1_Exists, 
    OBJECT_ID(N't2', N'U') AS t2_Exists
运行此操作后,表t2存在。以下是输出:

t1_Exists   t2_Exists
----------- -----------
NULL        NULL
Msg 2714,第16级,第6状态,第1行
数据库中已存在名为“t1”的对象

Msg 3902,第16级,状态1,第2行
提交事务请求没有相应的开始事务


您应该删除
GO
语句,以便回滚整个事务:

IF OBJECT_ID('dbo.t1', 'U') IS NOT NULL 
    DROP TABLE dbo.t1
IF OBJECT_ID('dbo.t2', 'U') IS NOT NULL 
    DROP TABLE dbo.t2
GO

SELECT OBJECT_ID(N't1', N'U') AS t1_Exists, OBJECT_ID(N't2', N'U') AS t2_Exists
GO
   
BEGIN TRANSACTION 

CREATE TABLE t1 (id INT)
CREATE TABLE t1 (id INT) -- Causes an error, since t1 already exists
CREATE TABLE t2 (id INT)

COMMIT TRANSACTION 

GO

SELECT OBJECT_ID(N't1', N'U') AS t1_Exists, OBJECT_ID(N't2', N'U') AS t2_Exist
当您在代码中放入“Go”语句时,每个Go之间的每个语句都被视为一个批处理,并单独执行,即使它们位于同一文件中。因此,为了避免这种情况,应该删除Begin和Commit事务之间的所有go语句。在你做出承诺之前。确保会话中是否存在活动事务,以使其更安全。像这样

IF OBJECT_ID('dbo.t1', 'U') IS NOT NULL 
DROP TABLE dbo.t1
IF OBJECT_ID('dbo.t2', 'U') IS NOT NULL 
DROP TABLE dbo.t2
GO

SELECT OBJECT_ID(N't1', N'U') AS t1_Exists, OBJECT_ID(N't2', N'U') AS t2_Exists
GO



BEGIN TRANSACTION 

CREATE TABLE t1 (id INT)


CREATE TABLE t1 (id INT)--Causes an error, since t1 already exists


CREATE TABLE t2 (id INT)

IF @@TRANCOUNT>0    
COMMIT TRANSACTION 



GO

SELECT OBJECT_ID(N't1', N'U') AS t1_Exists, OBJECT_ID(N't2', N'U') AS t2_Exist
IF OBJECT_ID('dbo.t1', 'U') IS NOT NULL 
DROP TABLE dbo.t1
IF OBJECT_ID('dbo.t2', 'U') IS NOT NULL 
DROP TABLE dbo.t2
GO

SELECT OBJECT_ID(N't1', N'U') AS t1_Exists, OBJECT_ID(N't2', N'U') AS t2_Exists
GO



BEGIN TRANSACTION 

CREATE TABLE t1 (id INT)


CREATE TABLE t1 (id INT)--Causes an error, since t1 already exists


CREATE TABLE t2 (id INT)

IF @@TRANCOUNT>0    
COMMIT TRANSACTION 



GO

SELECT OBJECT_ID(N't1', N'U') AS t1_Exists, OBJECT_ID(N't2', N'U') AS t2_Exist