Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Microsoft SQL Server Новый топик    Ответить
 Nasted Triggers (Вложенные триггеры)  [new]
cmaker
Member

Откуда:
Сообщений: 3
Всем привет! Я изучаю SQL и у меня возник вопрос по вложенным триггерам. Конечно, я понимаю, что их нужно избегать и по умолчанию они вообще отключены на MSSQL. Дело в том что степень вложенности триггеров максимальна и равна 32. У меня возникло любопытство что будет, если я просто сделаю рекурсивный триггер и получу ошибку. Ошибку я получил, всё отлично. Затем я подумал, а что если я самостоятельно буду управлять вложенностью(продолжать мне рекурсию дальше или нет). Зная, что каждая DML инструкция начинает неявную транзакцию, я написал условие в начале триггера, ссылаясь на глобальную переменную @@TRANCOUNT

Вот пример кода, который я выполнил
CREATE TABLE [Examples].[TTR](
	[Id] [int] NULL,
	[Name] [varchar](10) NOT NULL
)


Затем, вещаю простой триггер AFTER INSERT, на эту таблицу
CREATE TRIGGER [Examples].[MyTrigger] 
   ON [Examples].[TTR]  -- tableName 
   AFTER INSERT
AS  
	BEGIN
		IF @@TRANCOUNT < 2
			INSERT Examples.TTR(id, name) VALUES(1, 'Test'); 
	end

И просто выполняю INSERT в эту же таблицу
INSERT Examples.TTR
(
    Id,
    Name
)
VALUES
(
    0, -- Id - int
    '' -- Name - varchar
)

Для меня ожидаемое поведение было такое: Начнётся неявная транзакция, затем в таблицу вставится строчка, вызовется мой триггер, т.к. @@TRANCOUNT = 1 в этот момент, он вставит ещё одну строчку, что в свою очередь приведёт к приращению количества вложенных транзакций и условие не выполнится. Но вылетает ошибка, что достигнут максимальный уровень вложенности в 32 и транзакция откатывается.

При опросах на MSDN выяснилось, что не всё так просто и в таких ситуациях нужно использовать TRIGGER_NESTLEVEL. Но что не так !? Почему? Начинается неявная транзакция 100%, счётчик приращивается, а в IF не попадает. Очень странно всё это.
23 май 14, 10:29    [16059721]     Ответить | Цитировать Сообщить модератору
 Re: Nasted Triggers (Вложенные триггеры)  [new]
Зайцев Фёдор
Member

Откуда: Лужки
Сообщений: 5308
автор
"Зная, что каждая DML инструкция начинает неявную транзакцию"

это не так
автор
и в таких ситуациях нужно использовать TRIGGER_NESTLEVEL

конкретно в таких ситуациях можно отключить рекурсивные вызовы триггера
23 май 14, 10:34    [16059752]     Ответить | Цитировать Сообщить модератору
 Re: Nasted Triggers (Вложенные триггеры)  [new]
Glory
Member

Откуда:
Сообщений: 104760
cmaker
Зная, что каждая DML инструкция начинает неявную транзакцию,

Начинает. Только если транзакции еще не существует к моменту запуска DML
А если существует, то не начинает
23 май 14, 10:40    [16059780]     Ответить | Цитировать Сообщить модератору
 Re: Nasted Triggers (Вложенные триггеры)  [new]
cmaker
Member

Откуда:
Сообщений: 3
Начинает. Только если транзакции еще не существует к моменту запуска DML
А если существует, то не начинает[/quot]

Действительно. Спасибо большое за наводку. Странно что в отладчике он показывал мне другую картину, @@TRANCOUNT, всё-же, приращивался.

Вот документальное подтверждение, если кому будет интересно. Повнимательней сейчас загуглил.

http://technet.microsoft.com/ru-ru/library/ms190974(v=sql.105).aspx
23 май 14, 14:18    [16061502]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить