Откат вложенной транзакции и ошибка журнала - в Trigger, Sql Server 2008 - PullRequest
0 голосов
/ 03 января 2019

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

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

Пока все хорошо.

Чтобы проверить регистрацию в перехватчике, яЯ использую 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 Ответ

0 голосов
/ 03 января 2019

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

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

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

...