Откат вложенной транзакции и ошибка журнала - в 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)