我有一個存儲過程,在插入/更新/刪除的觸發器中調用。忽略觸發器中的錯誤
問題是這個SP裏面有一個不重要的代碼塊。 因此我想忽略這個代碼塊產生的任何錯誤。
我在TRY CATCH塊中插入了這個代碼塊。但讓我吃驚,我得到了以下錯誤:
當前事務無法提交,無法支持寫入日誌文件的操作。回滾事務。
然後我試圖使用SAVE & ROLLBACK TRANSACTION與TRY CATCH一起,太失敗,出現以下錯誤:
當前事務不能被提交併且不能被回滾到保存點。回滾整個交易。
我的服務器版本是:微軟的SQL Server 2008(SP2) - 10.0.4279.0(X64)
樣品DDL:
IF OBJECT_ID('TestTrigger') IS NOT NULL
DROP TRIGGER TestTrigger
GO
IF OBJECT_ID('TestProcedure') IS NOT NULL
DROP PROCEDURE TestProcedure
GO
IF OBJECT_ID('TestTable') IS NOT NULL
DROP TABLE TestTable
GO
CREATE TABLE TestTable (Data VARCHAR(20))
GO
CREATE PROC TestProcedure
AS
BEGIN
SAVE TRANSACTION Fallback
BEGIN TRY
DECLARE @a INT = 1/0
END TRY
BEGIN CATCH
ROLLBACK TRANSACTION Fallback
END CATCH
END
GO
CREATE TRIGGER TestTrigger
ON TestTable
FOR INSERT, UPDATE, DELETE
AS
BEGIN
EXEC TestProcedure
END
GO
代碼複製錯誤:
BEGIN TRANSACTION
INSERT INTO TestTable VALUES('data')
IF @@ERROR > 0
ROLLBACK TRANSACTION
ELSE
COMMIT TRANSACTION
GO
感謝您的建議。我實際上有一個服務代理機制,這就是我所說的非關鍵部分。我不希望主事務在服務代理機制失敗時回滾。我只會堅持當前的實現。謝謝你的幫助。 – Adi 2012-04-03 03:48:46
關於你最近的聲明你不應該這樣做......這是否意味着我們不應該有任何業務邏輯代碼直接或間接在觸發器內?如果是這樣,這不會使生活變得非常困難? – Jami 2015-06-29 11:13:08
@Sahand - 這取決於 - 這是「業務邏輯」,應該(可選)導致*原始*事務失敗?如果是這樣,那麼它應該在觸發器中(或者更好地,通過諸如外鍵或檢查約束等其他DRI直接表達)。或者,如果原始操作應該總是成功,而這個「業務邏輯」是分開的,那麼我會按照我在這個答案中所說的內容去使用某種形式的隊列來解耦處理。 *讀取*排隊更改的代碼可以像您想要的那樣複雜。 – 2015-06-29 12:08:07