IF (OBJECT_ID('AA','U') IS NOT NULL)
DROP TABLE AA
CREATE TABLE AA(ID INT)
SELECT * FROM AA
BEGIN TRAN
BEGIN TRY
INSERT INTO AA SELECT 1
INSERT INTO #BB SELECT 1
COMMIT TRAN;
END TRY
BEGIN CATCH
SELECT ERROR_MESSAGE() AS ErrorMessage
,ERROR_SEVERITY() AS ErrorSeverity
,ERROR_STATE() AS ErrorState
ROLLBACK TRAN;
END CATCH
/*運行結果:
(1 行受影響)
消息 208,級別 16,狀態 0,第 4 行
對象名 '#BB' 無效。
說明:A處已經執行;B處中斷操作,下面語句未執行
查詢表AA已經有數據,此時可手動繼續操作提交或回滾
*/
BEGIN TRAN
BEGIN TRY
INSERT INTO AA SELECT 1
INSERT INTO BB SELECT 1
COMMIT TRAN;
END TRY
BEGIN CATCH
SELECT ERROR_MESSAGE() AS ErrorMessage
,ERROR_SEVERITY() AS ErrorSeverity
,ERROR_STATE() AS ErrorState
ROLLBACK TRAN;
END CATCH
/*運行結果:
注意:【案例1】使用臨時表#BB,【案例2】使用表BB
選中代碼執行兩次,結果不一樣!
第一次執行結果(不捕獲異常),同【案例1】:
(1 行受影響)
消息 208,級別 16,狀態 0,第 4 行
對象名 '#BB' 無效。
第二次執行結果(捕獲異常):
ErrorMessage ErrorSeverity ErrorState
對象名 'BB' 無效。 16 1
*/
BEGIN TRAN
BEGIN TRY
INSERT INTO AA SELECT 1
INSERT INTO AA SELECT 'kk'
COMMIT TRAN;
END TRY
BEGIN CATCH
SELECT ERROR_MESSAGE() AS ErrorMessage
,ERROR_SEVERITY() AS ErrorSeverity
,ERROR_STATE() AS ErrorState
ROLLBACK TRAN;
END CATCH
/*運行結果(正常捕獲異常):
ErrorMessage ErrorSeverity ErrorState
在將 varchar 值 'kk' 轉換成數據類型 int 時失敗。 16 1
*/
BEGIN TRAN
BEGIN TRY
INSERT INTO AA SELECT 1
EXEC('INSERT INTO #BB SELECT 1')
COMMIT TRAN;
END TRY
BEGIN CATCH
SELECT ERROR_MESSAGE() AS ErrorMessage
,ERROR_SEVERITY() AS ErrorSeverity
,ERROR_STATE() AS ErrorState
ROLLBACK TRAN;
END CATCH
/*正常捕獲異常!
不報之前錯誤:對象名 '#BB' 無效。
但要求格式為:EXEC(@sql)
*/
SET XACT_ABORT ON
BEGIN TRAN
BEGIN TRY
INSERT INTO AA SELECT 1
INSERT INTO #BB SELECT 1
COMMIT TRAN;
END TRY
BEGIN CATCH
SELECT ERROR_MESSAGE() AS ErrorMessage
,ERROR_SEVERITY() AS ErrorSeverity
,ERROR_STATE() AS ErrorState
ROLLBACK TRAN;
END CATCH
SET XACT_ABORT OFF
/*運行結果:
(1 行受影響)
消息 208,級別 16,狀態 0,第 5 行
對象名 '#BB' 無效。
報錯,但是事務會自動回滾.
系統默認: SET XACT_ABORT OFF
當 SET XACT_ABORT 為 ON 時,如果執行 Transact-SQL 語句產生運行時錯誤,則整個事務將終止並回滾。
*/
SELECT (CASE WHEN (16384 & @@OPTIONS) = 16384 THEN 'ON' ELSE 'OFF' END) AS XACT_ABORT;
/*
1. 輕微錯誤(嚴重性級別為0-10):默認情況下不會給客戶程序發送錯誤消息,繼續工作。也就是說它無法被CATCH到
2. 中等錯誤(嚴重性級別為11-19):能夠被CATCH到(不管是在T-SQL里面還是在客戶程序里面)
3. 嚴重錯誤(嚴重性級別為20-25):SQL Server將強制把連接關掉。很顯然這也不可能被CATCH到
【重點提示!!】
由於業務的復雜或者系統性能問題,致使數據庫sql語句執行較久。
導致客戶端網頁已經連接超時(如設置為30秒)
此時數據庫批處理語句未執行完成,客戶session斷開,相當於中斷操作,類似【案例1】的中斷。
事務是沒有提交或回滾的,資源仍在占用,導致發生堵塞或死鎖!~
【解決方法】:
在批處理語句前加上 SET XACT_ABORT ON
當客戶端中斷的時候,未執行完成則回滾操作,及時釋放資源。
*/