忽略触发器中的错误 [英] Ignoring errors in Trigger

查看:89
本文介绍了忽略触发器中的错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个存储过程,该过程在Insert / Update / Delete的触发器中被调用。

I have a stored procedure which is called inside a trigger on Insert/Update/Delete.

问题是此SP内有某个代码块并不重要。
因此,我想忽略此代码块引起的任何错误。

The problem is that there is a certain code block inside this SP which is not critical. Hence I want to ignore any erros arising from this code block.

我将此代码块插入了TRY CATCH块中。但是令我惊讶的是,我得到了以下错误:

I inserted this code block inside a TRY CATCH block. But to my surprise I got the following error:

当前事务无法提交,并且不支持写入日志文件的操作。回滚交易。

The current transaction cannot be committed and cannot support operations that write to the log file. Roll back the transaction.

然后我尝试使用SAVE& ROLLBACK TRANSACTION和TRY CATCH一起也失败,并出现以下错误:

Then I tried using SAVE & ROLLBACK TRANSACTION along with TRY CATCH, that too failed with the following error:

当前事务无法提交,也无法回滚到保存点。回滚整个事务。

The current transaction cannot be committed and cannot be rolled back to a savepoint. Roll back the entire transaction.

我的服务器版本是:Microsoft SQL Server 2008(SP2)-10.0.4279.0(X64)

My server version is: Microsoft 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


推荐答案

我建议重新进行架构设计,以免中毒原始交易-也许让交易发送服务经纪人消息(或只是将相关数据插入某种形式的队列表),以便非关键部分可以在完全独立的交易中发生。

I'd suggest re-architecting this so that you don't poison the original transaction - maybe have the transaction send a service broker message (or just insert relevant data into some form of queue table), so that the "non-critical" part can take place in a completely independent transaction.

例如您的触发器将变为:

E.g. your trigger becomes:

CREATE TRIGGER TestTrigger
ON TestTable
FOR INSERT, UPDATE, DELETE 
AS
BEGIN
    INSERT INTO QueueTable (Col1,Col2)
    SELECT COALESCE(i.Col1,d.Col1),COALESCE(i.Col2,d.Col2) from inserted i,deleted d
END
GO

不应该在触发器中执行可能会失败的任何操作,除非您 do 想要强制启动触发器操作的事务也失败。

You shouldn't do anything inside a trigger that might fail, unless you do want to force the transaction that initiated the trigger action to also fail.

这篇关于忽略触发器中的错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆