2012-11-30 43 views
0

我有兩個類似的TSQL腳本,其中SET XACT_ABORT爲ON。我希望_test表在腳本執行後不存在,因爲我故意使用包含在事務中的語句來引發錯誤。XACT_ABORT與批處理中的sp_recompile行爲不一致

第一個腳本正確回退_test表的創建。

SET XACT_ABORT ON 
GO 
BEGIN TRANSACTION 
CREATE TABLE dbo._test(ID int IDENTITY(1, 1) NOT NULL) 
EXEC sp_does_not_exist --raises error! 
GO 
IF @@TRANCOUNT > 0 
    COMMIT; 

然而,第二個腳本不回滾的_test創建和表腳本執行後存在:

SET XACT_ABORT ON 
GO 
BEGIN TRANSACTION 
CREATE TABLE dbo._test(ID int IDENTITY(1, 1) NOT NULL) 
EXEC sp_recompile sp_does_not_exist; --raises error! 
GO 
IF @@TRANCOUNT > 0 
    COMMIT; 

爲什麼第二腳本不執行後刪除_test表?

回答

0

你還沒有提到你的SQL Server版本,但由於你的腳本中唯一的區別是sp_recompile,所以這看起來是個好地方。在2008R2它具有以下的邏輯:

BEGIN TRANSACTION 
-- CHECK VALIDITY OF OBJECT NAME -- 
-- (1) Must exist in current database 
-- (2) Must be a table or an executable object 
select @objid = object_id(@objname, 'local') 

    if @objid is null OR 
     (ObjectProperty(@objid, 'IsTable') = 0 AND 
     ObjectProperty(@objid, 'IsExecuted') = 0) 
    begin 
     COMMIT TRANSACTION 
     raiserror(15165,-1,-1 ,@objname) 
     return @@error 
    end 

所以sp_recompile檢查對象之前存在它試圖直接訪問它,並且如果未發現它會引發與嚴重性-1的錯誤。 RAISERRORstates的文檔將嚴重性級別小於零的操作解釋爲零,並且嚴重性級別爲states的文檔在嚴重性爲零時不會引發系統錯誤。

事實上,加入RAISERRORsp_recompile到腳本表明,它並不影響@@TRANCOUNT

SET XACT_ABORT ON 
GO 
BEGIN TRANSACTION 
CREATE TABLE dbo._test(ID int IDENTITY(1, 1) NOT NULL) 
select @@trancount as 'before raiserror'  
raiserror(15165,-1,-1 ,'sp_does_not_exist') 
select @@trancount as 'after raiserror' 

GO 
IF @@TRANCOUNT > 0 
    COMMIT; 

@@TRANCOUNT爲1,引發錯誤之前和之後的,所以沒有什麼可觸發回滾。但是,如果你這樣做,第二SELECT永遠不會執行,因爲該錯誤已被提出的「直接」數據庫引擎:

SET XACT_ABORT ON 
GO 
BEGIN TRANSACTION 
CREATE TABLE dbo._test(ID int IDENTITY(1, 1) NOT NULL) 
select @@trancount as 'before raiserror'  
exec sp_does_not_exist 
select @@trancount as 'after raiserror' 

GO 
IF @@TRANCOUNT > 0 
    COMMIT; 
+0

它顯示爲紅色SSMS中表示「正確」的錯誤。我假設它使用嚴重性16'select * from sys.messages where message_id = 15165'。 RAISERROR'自己提出的錯誤[不**通常會導致'XACT_ABORT'回滾](http://www.sommarskog.se/error-handling-I.html#XACT_ABORT)。不確定系統存儲過程中是否有任何不同。 –

相關問題