回滚嵌套事务和日志错误-在触发器中,SQL Server 2008

时间:2019-01-03 15:20:10

标签: tsql transactions rollback nested-transactions

我在对表的插入语句上有一个触发器(可能会修改插入值)。 如果触发器中发生错误,我要记录它。并且仍必须插入INSERT。 因此,我使用了一个TRY / CATCH块,其中catch部分将进行日志记录。 问题是我只能回滚整个事务,然后再记录。但是然后插入内容也会回滚。

在Sql Server 2008上运行...

到目前为止很好。

要测试catch部分中的日志记录,我正在使用RAISERROR。 (也许这是一个问题?我将回到该部分)。然后,我将插入内容运行到表中。

在触发器中,我放置了一个BEGIN TRANSACTION triggerTransaction2。我命名了它,因此可以回滚该特定事务。注意,insert语句已经开始了事务。 但是问题是我无法回滚嵌套的(triggerTransaction2)事务。仅整个交易(使用不带名称的ROLLBACK)。

如果我看着XACT_STATE(),那么它是-1。这应该表示“它只能请求完全回滚交易”。

我试图简化代码,并希望它仍然有意义。 我也遵循了这个example-对我有用,但也不是嵌套事务。

所以我在想,将RAISERROR与所选值一起使用不是很好。

触发器的伪代码:

CREATE TRIGGER [dbo].[Trigger_SomeTableStatus]
ON [dbo].[SomeTable]
FOR INSERT
AS

BEGIN
    SET NoCount ON
    -- declaring som variables;         DECLARE @isActive BIT;

    BEGIN TRY

        BEGIN TRANSACTION triggerTransaction2       
        -- SAVE TRANSACTION triggerTransaction2

        -- some logic ... 
        RAISERROR(' Test error message; *failed* ', 16, 1);

        COMMIT TRANSACTION triggerTransaction2

    END TRY
    BEGIN CATCH

        -- HERE  XACT_STATE() = -1)
        ROLLBACK TRANSACTION   triggerTransaction2      -- Cannot rollback with the name 

        BEGIN TRY
            BEGIN TRANSACTION triggerTransactionLog
            -- Do the logging..
            COMMIT TRANSACTION triggerTransactionLog
        END TRY
        BEGIN CATCH
        --      -- Logging of error failed...
        END CATCH
    END CATCH
END

1 个答案:

答案 0 :(得分:0)

是的,这是因为当您进行“回滚”时,整个交易都将被取消。 您必须在内存中创建一个表,例如:

DECLARE @Log AS TABLE 
(
    Description NVARCHAR(100)
);

然后,在@Log表中插入要登录的内容。 最后,将@Log表中的内容插入到END TRY和END CATCH之前(或SP结束之前)的DB日志表中。