Откат вложенной транзакции и ошибка журнала - в Trigger, Sql Server 2008

У меня есть триггер (который может изменить значение на вставке) на операторах вставки в таблицу. Если в триггере возникает ошибка, я хочу записать ее. И вставка все еще должна быть вставлена. Поэтому я использую блок TRY / CATCH, где часть catch будет выполнять регистрацию. Проблема в том, что я могу только откатить всю транзакцию, а затем войти. Но затем вставка также откатывается.

Работает на Sql Server 2008...

Все идет нормально.

Чтобы проверить регистрацию в части catch, я использую RAISERROR. (Может быть, это проблема? Я вернусь к этой части). Затем я запускаю вставку к столу.

В триггере я поместил BEGIN TRANSACTION triggerTransaction2. Я назвал его, чтобы я мог откатить эту конкретную транзакцию. Обратите внимание также, что оператор вставки начал транзакцию. Но проблема в том, что я не могу откатить вложенную транзакцию (triggerTransaction2). Только вся транзакция (с использованием ROLLBACK без имени).

Если я смотрю на XACT_STATE(), то это -1. Что должно означать, что "он может только запросить полный откат транзакции".

Я попытался упростить код и надеюсь, что он по-прежнему имеет смысл. Также я следовал этому примеру - и это работает для меня, но это также не с вложенной транзакцией.

Так что я думаю, либо не хорошо использовать 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 ответ

Да, это потому, что когда вы выполняете ROLLBACK, полная транзакция отменяется. Вы должны создать таблицу в памяти, как:

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

Затем вставьте то, что вы хотите войти в таблицу @Log. Наконец, вставьте содержимое таблицы @Log в таблицу Log в вашей БД перед END TRY и END CATCH (или непосредственно перед концом SP)

Другие вопросы по тегам