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

Откуда: Ленинград
Сообщений: 86
Добрый день,
Почему после COMMIT в триггере обрывается выполнение скрипта? Т.е. почему в примере не выводится сообщение 'после триггера'?

CREATE TABLE t1 (i int primary key)
go

CREATE trigger t1_test ON t1 
AFTER INSERT
AS
IF @@TRANCOUNT>0 COMMIT TRAN
print 'внутри триггера'
go

print 'до триггера'
INSERT t1(i) values(1)
print 'после триггера'
go

drop table t1
9 фев 05, 15:08    [1311003]     Ответить | Цитировать Сообщить модератору
 Re: Почему после COMMIT в триггере обрывается выполнение скрипта?  [new]
iSestrin
Member

Откуда: Новосибирск
Сообщений: 3811
CREATE TABLE t1 (i int primary key)
go

CREATE trigger t1_test ON t1
AFTER INSERT
AS
begin tran
IF @@TRANCOUNT>0 COMMIT TRAN
print 'внутри триггера'
go

print 'до триггера'
INSERT t1(i) values(1)
print 'после триггера'
go

drop table t1
9 фев 05, 15:12    [1311023]     Ответить | Цитировать Сообщить модератору
 Re: Почему после COMMIT в триггере обрывается выполнение скрипта?  [new]
Smirnov Anton
Member

Откуда: Н.Новгород
Сообщений: 3220
а смысл коммита внутри триггера можно узнать?
9 фев 05, 15:16    [1311039]     Ответить | Цитировать Сообщить модератору
 Re: Почему после COMMIT в триггере обрывается выполнение скрипта?  [new]
tt12
Member

Откуда: Ленинград
Сообщений: 86
2 Smirnov Anton
Коммит внутри тригера нужен чтобы при ошибке внутри триггера не откатывалось действие, вызвавшее триггер.
9 фев 05, 15:52    [1311193]     Ответить | Цитировать Сообщить модератору
 Re: Почему после COMMIT в триггере обрывается выполнение скрипта?  [new]
Критик
Member

Откуда: Москва / Калуга
Сообщений: 33340
Блог
>tt12

Странно, как я понимаю, триггеры служат для сохранения целостности БД... обычно вроде так, но видимо у вас по-другому... )
9 фев 05, 15:58    [1311215]     Ответить | Цитировать Сообщить модератору
 Re: Почему после COMMIT в триггере обрывается выполнение скрипта?  [new]
Smirnov Anton
Member

Откуда: Н.Новгород
Сообщений: 3220
tt12
2 Smirnov Anton
Коммит внутри тригера нужен чтобы при ошибке внутри триггера не откатывалось действие, вызвавшее триггер.

а что может вызвать ошибку внутри триггера?
это что - то вроде перестраховки?
9 фев 05, 16:13    [1311268]     Ответить | Цитировать Сообщить модератору
 Re: Почему после COMMIT в триггере обрывается выполнение скрипта?  [new]
Glory
Member

Откуда:
Сообщений: 104760
tt12
2 Smirnov Anton
Коммит внутри тригера нужен чтобы при ошибке внутри триггера не откатывалось действие, вызвавшее триггер.

А также все действия которые были в этой транзакции ДО команды вызвавшей срабатывание триггера ???
9 фев 05, 16:15    [1311282]     Ответить | Цитировать Сообщить модератору
 Re: Почему после COMMIT в триггере обрывается выполнение скрипта?  [new]
Smirnov Anton
Member

Откуда: Н.Новгород
Сообщений: 3220
to Glory
да, это железный аргумент
use tempdb
create table t1(i int)
create table t2(i int)
go
create trigger tr1 on t1
for insert 
as
 if @@TRANCOUNT>0 COMMIT
go
begin tran
insert into t2 select 1
insert into t1 select 1
rollback
go
select * from t2
--а должна быть пустой!!!
select * from t1
--а должна быть пустой!!!
go
drop table t1
drop table t2
9 фев 05, 16:21    [1311299]     Ответить | Цитировать Сообщить модератору
 Re: Почему после COMMIT в триггере обрывается выполнение скрипта?  [new]
tt12
Member

Откуда: Ленинград
Сообщений: 86
Да, это можно назвать перестраховкой.
В триггере запускается довольно большая процедура. Независимо от наличия в ней ошибок действие, вызвавшее триггер, должно отработать. Может правильнее будет запролнять в триггере некую таблицу "очередь" из вызовов этой процедуры, и из очереди выполнять процедуру, уже не в триггере.
9 фев 05, 16:23    [1311306]     Ответить | Цитировать Сообщить модератору
 Re: Почему после COMMIT в триггере обрывается выполнение скрипта?  [new]
Smirnov Anton
Member

Откуда: Н.Новгород
Сообщений: 3220
исходя из приведённого выше примера можно с уверенностью сказать, что соммit в тригере делать не стоит(транзакцию не вы он открыл и не ему её закрывать)
а триггер и довольно большая процедура - слова, которые плохо сочетаются.
9 фев 05, 16:31    [1311330]     Ответить | Цитировать Сообщить модератору
Между сообщениями интервал более 1 года.
 Зачем такое может быть нужно и "Что делать?"  [new]
IgorTaDaDaDa
Member

Откуда: Australia
Сообщений: 88
Хотелось бы вернуться к этой теме и попросить _доброго_ совета, как поступить правильно в схожей ситуации.

Есть приложение с которым нужно интегрировать свою систему. Приложение дорогое и вендор разумеется не позволит туда чего-то своё запихнуть.

Разрешено реплицировать от них к себе.

Идея которая описана в топике выше основывается на предположении что:

1. Мы пишем триггера на репликационние таблицы
2. Внутри триггера мы создаем временную таблицу
3. Сохраняем туда из Inserted (например)
4. Делаем COMMIT так как нам нужно, чтобы обновление нашей базы и возможные ROLLBACK в процессе не затронули процесс репликации
5. Начинаем свою транзакцию внутри триггера
6. Обновляем свою базу на основании данных, которые сохранили на этапе 3
7. Делаем ROLLBACK или COMMIT, который как мы ожидаем будет затрагивать пункты 6 и 7

Такой процесс работает с одной системой, но не работает с другой. Какая между ними разница?

Во второй системе на стороне Distributor выполняется транзакция (BEGIN-UPDATE-INSERT-COMMIT). Так вот пунк 4 приводит к тому что на стороне SUBSCRIBERa выполняется только UPDATE и пункт 4 каким-то боком заканчивает весь процесс. [sp_MSins_dboEMPOS] уже не виден в Profiler, как будто его и не было.

Отсюда 2 вопроса:

1. Главный. Как отслеживать такие события правильно в принципе?

2. Второстепенный. Почему подход, описанный выше, не работает?

Большое спасибо
19 ноя 09, 05:05    [7948318]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить