Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / Firebird, InterBase [игнор отключен] [закрыт для гостей] / trigger active on transaction commit / 19 сообщений из 19, страница 1 из 1
09.10.2014, 22:19
    #38772396
NickDee
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
trigger active on transaction commit
Это после коммита, или до? Судя по тому что там можно написать insert, транзакция ещё не закомичена.
DDL after-триггеры уже сработали? Или они сработают после этого триггера?

Логично было бы иметь before commit и after commit. В before commit ещё можно писать в контексте транзакции, а в after commit уже нельзя, по аналогии с таблицами.

Так же логично было бы иметь триггер before connect, где можно было бы проверить auth и дополнительные параметры от клиента, которые идут в DPB или прописаны в серверном конфиге, и иметь триггер after connect, где можно было бы уже выполнить какие-нить стэйтменты в автономках.
...
Рейтинг: 0 / 0
09.10.2014, 22:48
    #38772406
kdv
kdv
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
trigger active on transaction commit
NickDee,

on commit (rollback) - это before. смысла в триггере after commit не вижу совершенно, т.к. в нем делать нельзя ничего, совсем, даже exception вызывать поздно.

разницы между before и after connect не вижу. Это триггер на успешный коннект, в котором можно проверить что нужно, и либо обломить коннект, либо оставить в покое, что как раз совмещается и по before, и по after.
...
Рейтинг: 0 / 0
09.10.2014, 22:54
    #38772408
dimitr
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
trigger active on transaction commit
NickDeeТак же логично было бы иметь триггер before connect
и в каком-таком контексте его, пардон, иметь? Если к базе мы еще не подключились.
...
Рейтинг: 0 / 0
09.10.2014, 23:10
    #38772421
Dimitry Sibiryakov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
trigger active on transaction commit
kdvсмысла в триггере after commit не вижу совершенно, т.к. в нем делать нельзя ничего, совсем, даже exception вызывать поздно.
Зато в нём можно записать куда-нибудь "наружу" факт свершившегося коммита и быть уверенным, что это соответствует действительности и никакие ошибки в DFW эту транзакцию уже не откатят. Собственно, именно поэтому и создан соответствующий тикет в трекере.
...
Рейтинг: 0 / 0
09.10.2014, 23:19
    #38772428
kdv
kdv
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
trigger active on transaction commit
Dimitry Sibiryakov,

все равно on commit/rollback являются скорее debug-триггерами, чем триггерами, которые можно оставлять для production. Хуже в отношении производительности могут быть только триггеры на select :-)
...
Рейтинг: 0 / 0
10.10.2014, 07:03
    #38772540
NickDee
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
trigger active on transaction commit
kdvсмысла в триггере after commit не вижу совершенно, т.к. в нем делать нельзя ничего, совсем, даже exception вызывать поздно.
Там место для кода, который должен отработать после усепшного применения DDL.
...
Рейтинг: 0 / 0
10.10.2014, 08:49
    #38772613
Симонов Денис
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
trigger active on transaction commit
NickDee,

для DDL кода есть DDL триггеры
...
Рейтинг: 0 / 0
10.10.2014, 10:09
    #38772695
Fr0sT-Brutal
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
trigger active on transaction commit
kdvХуже в отношении производительности могут быть только триггеры на select :-)
Все так плохо? Недавно добавил у себя триггер на commit - ловлю тормознутые транзакции. Соответственно, там и mon$ дергается, чтобы время старта получить. Это не гуд?
...
Рейтинг: 0 / 0
10.10.2014, 10:26
    #38772723
Таблоид
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
trigger active on transaction commit
Fr0sT-BrutalНедавно добавил у себя триггер на commit - ловлю тормознутые транзакции. Соответственно, там и mon$ дергается , чтобы время старта получить. Это не гуд?Нет, не гут. И даже больше: возможен капут.
А ловить тормоза надо user-трейсом, выставляя time_threshold = 1000 (например) и давать ему поработать 1-2 часа.
...
Рейтинг: 0 / 0
10.10.2014, 11:00
    #38772810
kdv
kdv
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
trigger active on transaction commit
Fr0sT-BrutalВсе так плохо?
1. ты используешь триггер on commit для отладки (как я и говорил выше)
2. "тормознутых транзакций" не бывает. Бывают тормознутые запросы, которые отлавливаются так, как сказал Таблоид.
...
Рейтинг: 0 / 0
10.10.2014, 11:56
    #38772915
Fr0sT-Brutal
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
trigger active on transaction commit
ТаблоидА ловить тормоза надо user-трейсом, выставляя time_threshold = 1000 (например) и давать ему поработать 1-2 часа.
В моем случае не выйдет, делал как диагностику на всякие экзотические случаи в системе 24/7 с разношерстными клиентами.

kdv, под тормознутыми подразумевал те, которые длятся больше лимита.

А триггер на transaction start тоже не гуд? А то у меня на нем уже более значительные действия повешены.
...
Рейтинг: 0 / 0
10.10.2014, 12:24
    #38772987
NickDee
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
trigger active on transaction commit
Симонов ДенисNickDee,

для DDL кода есть DDL триггеры
DDL триггеры "after create" оказывается запускаются не по commit, а сразу после "create table".
Т.е. в OnCommit уже вся инфа по таблице есть (в системных таблицах), хотя сама таблица ещё не создана, и вполне может произойти отлуп её создания уже после OnCommit.
И именно поэтому нужен OnAfterCommit.

Маленькое отступление...
Хреново что "create table" и реальное создание таблицы разделены во времени. Приходится городить огород с autonomous transaction и пр, и отказываться от ddl-стэйтментов в ddl-триггерах (да и в любых других тоже).
Как мы кстати накатываем патчи на боевую бд? Как положено? Атомарно? В одной транзакции? Нет, архетиктура FB нам это пока что запрещает.
А ведь как это естественно, написать "create table T", потом вставить записи в T, потом создать индексы, потом одним коммитом всё подтвердить, ведь транзакции именно для этого. Нет, мы делаем метаданные отдельно, данные отдельно, а если что-то ломается по дороге, то получаем гору метаданных в перемешку с данными, которую потом откатить можно только вручную, и то если старая версия доступна.
...
Рейтинг: 0 / 0
10.10.2014, 12:35
    #38772998
Мимопроходящий
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
trigger active on transaction commit
Hello, Nickdee!
You wrote on 10 октября 2014 г. 12:34:11:

Nickdee> А ведь как это естественно, написать "create table T",
потом вставить
> записи в T, потом создать индексы, потом одним коммитом всё подтвердить,
> ведь транзакции именно для этого. нет.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
10.10.2014, 12:52
    #38773027
kdv
kdv
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
trigger active on transaction commit
NickDeeИ именно поэтому нужен OnAfterCommit.
для чего именно он тебе нужен? Как ты отличишь этот aftercommit обычной транзакции от "ddl-транзакции"?
...
Рейтинг: 0 / 0
10.10.2014, 16:00
    #38773386
NickDee
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
trigger active on transaction commit
kdvNickDeeИ именно поэтому нужен OnAfterCommit.
для чего именно он тебе нужен?
Я ж написал, или тебе всю задачу целиком описать?
kdvКак ты отличишь этот aftercommit обычной транзакции от "ddl-транзакции"?
Мне сама транзакция скажет что она DDL, вот тут:
Код: sql
1.
2.
3.
4.
5.
create trigger trig_ddl before any ddl statement
as
begin
   --
end


Опишу пожалуй задачу.
Есть табличка R$Tables, и табличка R$TableFields, как продолжения RDB$RELATIONS и RDB$RELATION_FIELDS.
Нужно чтобы они всегда находились в консистентном состоянии, т.е. если кто-то делает create table, или alter, или drop, то мне нужно автоматом править данные в этих табличках.
Решение придумал такое:
создаём триггер:
Код: sql
1.
2.
3.
4.
5.
6.
7.
create trigger R$DDL_BeforeTouchTable BEFORE CREATE TABLE or ALTER TABLE or DROP TABLE as
begin
  if (rdb$get_context('USER_TRANSACTION', 'ParallelTransId') is null) then
    rdb$set_context('USER_TRANSACTION', 'ParallelTransId', 
      CreateTransaction(CURRENT_CONNECTION, 'isc_tpb_read_committed, isc_tpb_rec_version, isc_tpb_nowait')
    );
end;


Далее в триггере ловим create table, и там в параллельной транзакции пишем инфу:
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
CREATE OR ALTER trigger "R$DDL_AfterCreateTable"
active after create table position 0
AS
  declare FieldName varchar(255);
  declare TableName varchar(255);
  declare TableId integer;
  declare FieldId integer;
  declare ParallelTransactionId bigint;
  declare InParams R$TParams;
  declare ReturningValues R$TReturningValues;
begin
  TableName = rdb$get_context('DDL_TRIGGER', 'OBJECT_NAME');
  ParallelTransactionId = rdb$get_context('USER_TRANSACTION', 'ParallelTransId');
  InParams = R$CreateQueryParams;
  R$AddStrParam(InParams, 'TableName', :TableName);
  ExecQueryWithParams(ParallelTransactionId, 'insert into R$Tables (R$Name, ...) values (:TableName, ...) returning id into :TableId', InParams, ReturningValues);
  TableId = R$GetIntReturnValue(ReturningValues, 'TableId');

  InParams = R$CreateQueryParams;
  R$AddIntParam(InParams, 'TableId', :TableId);
  R$AddStrParam(InParams, 'FieldName', NULL);
  for select rdb$field_name from rdb$relation_fields where rdb$relation_name = TableName order by rdb$field_position into :FieldName do
  begin
    R$SetStrParam(InParams, 'FieldName', :FieldName);
    ExecQueryWithParams(ParallelTransactionId, 'insert into R$TableFields (R$TableId, R$Name, ...) values (:TableId, :TableName, ...)', InParams, NULL);
  end
end

И похожие триггеры на Alter и Drop.
И триггеры чтобы подтвердить или откатить изменения, что мы наделали в параллельной транзакции:
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
CREATE OR ALTER trigger R$DDL_OnCommit
active on transaction commit position 0
AS
  declare ParallelTransactionId bigint;
begin
  ParallelTransactionId = rdb$get_context('USER_TRANSACTION', 'ParallelTransId');
  if (not (ParallelTransactionId is null)) then 
    CommitTransaction(ParallelTransactionId);
end;

CREATE OR ALTER trigger R$DDL_OnRollback
active on transaction rollback position 0
AS
  declare ParallelTransactionId bigint;
begin
  ParallelTransactionId = rdb$get_context('USER_TRANSACTION', 'ParallelTransId');
  if (not (ParallelTransactionId is null)) then 
    RollbackTransaction(ParallelTransactionId);
end


И был бы профит, если бы R$DDL_OnCommit была after commit.
И конечно ещё больший профит был бы если бы не пришлось городить весь этот огород с параллельной транзакцией. Но Мимопроходящий всё ещё категорически против :)
...
Рейтинг: 0 / 0
10.10.2014, 18:30
    #38773666
Ivan_Pisarevsky
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
trigger active on transaction commit
NickDeeЕсть табличка R$Tables, и табличка R$TableFields, как продолжения RDB$RELATIONS и RDB$RELATION_FIELDS.
Нужно чтобы они всегда находились в консистентном состоянии, т.е. если кто-то делает create table, или alter, или drop, то мне нужно автоматом править данные в этих табличках.сделать наоборот? праивть таблички, а триггер на оный пусть разность метаданные... правда выглядит криво.
...
Рейтинг: 0 / 0
10.10.2014, 19:16
    #38773724
Dimitry Sibiryakov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
trigger active on transaction commit
NickDeeДалее в триггере ловим create table, и там в параллельной транзакции пишем инфу:)
И конечно ещё больший профит был бы если бы не пришлось городить весь этот огород с параллельной транзакцией.

Так не городи, кто тебя заставляет-то?.. Откатится транзакция - откатятся и изменения в твоих табличках.
...
Рейтинг: 0 / 0
11.10.2014, 12:29
    #38773974
NickDee
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
trigger active on transaction commit
Dimitry SibiryakovNickDeeДалее в триггере ловим create table, и там в параллельной транзакции пишем инфу:)
И конечно ещё больший профит был бы если бы не пришлось городить весь этот огород с параллельной транзакцией.

Так не городи, кто тебя заставляет-то?.. Откатится транзакция - откатятся и изменения в твоих табличках.
Я слышал что миксить DDL и DML в одной транзакции нехорошо, что могут быть непредсказуемые последствия. Это уже не так? Так я буду миксить, с удовольствием.

И ещё:
Firebird 3.0 Alpha 2 RN3. DDL trigger actions are executed only when committing the transaction in which the affected DDL command runs."DDL trigger actions" - это что, в переводе на русский? Если это "DDL statement actions", тогда да. А если это "DDL trigger", тогда нет, они выполняются сразу.
...
Рейтинг: 0 / 0
11.10.2014, 13:47
    #38773991
Dimitry Sibiryakov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
trigger active on transaction commit
NickDeeЯ слышал...
...звон. Вставлять записи в свежесозданную таблицу действительно чревато боком. В любую другую - проблем нет.
...
Рейтинг: 0 / 0
Форумы / Firebird, InterBase [игнор отключен] [закрыт для гостей] / trigger active on transaction commit / 19 сообщений из 19, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]