Transaction count after EXECUTE indicates a mismatching number of BEGIN and COMMIT statements


Transaction count after EXECUTE indicates a mismatching number of BEGIN and COMMIT statements

開始想寫一個過程,根據一個項目的數據庫的一個表的導數據到另一個數據庫中去,本來在本地測試時蠻好的,但是將過程升級到生產服務器之后運行之后,根據下面類似的錯誤信息發現是生產服務器上引用的數據庫名不對。

Msg 208, Level 16, State 1, Procedure test_sp, Line 10
Invalid object name 'test.dbo.col1'.
Msg 266, Level 16, State 2, Procedure test_sp, Line 10
Transaction count after EXECUTE indicates a mismatching number of BEGIN and COMMIT statements. Previous count = 0, current count = 1

出現了這個錯之后就去查了下需要插入的表,發現鎖表了,所以猜測是不是剛剛運行的過程的事務沒有回滾(或提交)。就關閉當前查詢窗口,出現如下信息證實了猜測:
enter description here
但是過程中的TRY CATCH語句塊中已經寫有ROLLBACK了。此時,不得不懷疑是不是自己寫的TRY CATCH有問題,首先在過程中添加SELECT 1/0,對於這一錯誤ROLLBACK是起作用的。后來就去MSDNTRY CATCH幫助文檔,發現有這么一段說明:
enter description here
這個完全符合我遇到的情況,所以原來就是引用表的數據庫名寫錯,造成致命性錯誤,使得CATCH捕捉不到異常,所以事務沒能ROLLBACK

演示

我就改寫我的過程來演示遇到的問題和解決這個問題的方案。T1表中只有3條數據
enter description here

CREATE PROCEDURE [dbo].[test_sp] AS BEGIN TRY BEGIN TRAN SET NOCOUNT ON;         
        INSERT INTO T1( col1, col2 )VALUES( 3,3);

        SELECT * FROM T1;

        SELECT * FROM [AdventureWorks2012].[dbo].[T2] COMMIT TRAN;
END TRY BEGIN CATCH ROLLBACK TRAN;
    
    THROW;
END CATCH 

查詢1窗口執行test_sp過程

EXEC test_sp

--連接上執行的 BEGIN TRANSACTION 語句的數目
SELECT @@TRANCOUNT AS Trancount 

 

enter description here

1460734370861.jpg

 

 

enter description here

1460736223442.jpg

如果想關閉當前 查詢1窗口,彈出信息:

 

 

enter description here

1460734736433.jpg

 

查詢2窗口查詢T1[AdventureWorks2012].[dbo].[T2]

--查詢T1
SELECT * FROM T1;

T1一直被查詢1的事務占用:

 

enter description here

1460734465672.jpg

 

--查詢T2
SELECT * FROM [AdventureWorks2012].[dbo].[T2] 

T2沒有創建:

 

enter description here

1460734518647.jpg

 

解決方案

首先使用KILL命令將查詢1的連接給斷開,然后在test_sp中設置XACT_ABORTON。如果XACT_ABORTON時,如果執行 Transact-SQL 語句產生運行時錯誤,則整個事務將終止並回滾;為 OFF 時,有時只回滾產生錯誤的 Transact-SQL 語句,而事務將繼續進行處理。 如果錯誤很嚴重,那么即使 SET XACT_ABORT 為 OFF,也可能回滾整個事務。 OFF 是默認設置。

SET XACT_ABORT ON; 

我們在查詢1窗口中重新運行,順帶嘗試關閉窗口:

EXEC test_sp

SELECT @@TRANCOUNT AS Trancount --查詢T1 SELECT * FROM T1;

 

enter description here

1460735835769.jpg

 

 

enter description here

1460736150990.jpg

 

 

enter description here

1460736007326.jpg

@@TRANCOUNT為0, T1表還是只有3條紀錄,說明事務順利的終止並且回滾了。

 

我們在AdventureWorks2012數據庫中創建t2

CREATE TABLE t2 (col1 int) 

查詢1中先運行一遍將第4條數據插入,再運行第二遍。

EXEC test_sp 

 

enter description here

1460736881949.jpg

由於主鍵約束,拋出異常,我們可以檢查當前連接的事務連接數也是 0

 

SELECT @@TRANCOUNT AS Trancount 

 

enter description here

1460736950117.jpg

 

結論

設置XACT_ABORTON時,即使過程中沒有TRY CATCH,如果語句導致任何異常才會發生回滾。所以我們要靈活使用XACT_ABORT,如果使用TRY CATCH能夠捕捉所有需要解決的錯誤時,我們就不必開啟XACT_ABORT,只有錯誤比較嚴重時才考慮XACT_ABORTON

所以,我應該滾回去修改引用的數據庫名就好了。

參考:
http://www.cnblogs.com/chenxizhang/archive/2008/07/29/1255737.html
https://technet.microsoft.com/zh-cn/library/ms164086.aspx
https://msdn.microsoft.com/zh-cn/library/ms188792(v=sql.120).aspx
https://www.mssqltips.com/sqlservertip/4018/sql-server-transaction-count-after-execute-indicates-a-mismatching-number-of-begin-and-commit-statements/


返回頂部


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM