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


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

在查詢2窗口查詢T1
和[AdventureWorks2012].[dbo].[T2]
--查詢T1
SELECT * FROM T1;
表T1
一直被查詢1的事務占用:

--查詢T2
SELECT * FROM [AdventureWorks2012].[dbo].[T2]
T2
沒有創建:

解決方案
首先使用KILL
命令將查詢1的連接給斷開,然后在test_sp
中設置XACT_ABORT
為ON。如果XACT_ABORT
為ON時,如果執行 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;



@@TRANCOUNT
為0,
T1
表還是只有3條紀錄,說明事務順利的終止並且回滾了。
我們在AdventureWorks2012
數據庫中創建t2
CREATE TABLE t2 (col1 int)
在查詢1中先運行一遍將第4條數據插入,再運行第二遍。
EXEC test_sp

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

結論
設置XACT_ABORT
為ON時,即使過程中沒有TRY CATCH
,如果語句導致任何異常才會發生回滾。所以我們要靈活使用XACT_ABORT
,如果使用TRY CATCH
能夠捕捉所有需要解決的錯誤時,我們就不必開啟XACT_ABORT
,只有錯誤比較嚴重時才考慮XACT_ABORT
為ON。
所以,我應該滾回去修改引用的數據庫名就好了。
參考:
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/
返回頂部