powered by simpleCommunicator - 2.0.53     © 2025 Programmizd 02
Форумы / PostgreSQL [игнор отключен] [закрыт для гостей] / Всем привет! Поговорим про отключение триггеров
17 сообщений из 17, страница 1 из 1
Всем привет! Поговорим про отключение триггеров
    #39760593
PCContra
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Всем привет!

У меня вопрос такой (возможности самому проверить нет) Вот что начитал в мануале:
The ability to temporarily enable or disable a trigger is provided by ALTER TABLE, not by
ALTER
TRIGGER
, because
ALTER TRIGGER
has no convenient way to express the option of enabling or
disabling all of a table’s triggers at once.
ALTER TABLE
DISABLE TRIGGER [trigger_name| ALL | USER ]
ENABLE TRIGGER [trigger_name| ALL | USER ]
ENABLE REPLICA TRIGGERtrigger_name
ENABLE ALWAYS TRIGGERtrigger_name
DISABLE
/
ENABLE [ REPLICA | ALWAYS ] TRIGGER
These forms configure the firing of trigger(s) belonging to the table. A disabled trigger is still
known to the system, but is not executed when its triggering event occurs. For a deferred trigger,
the enable status is checked when the event occurs, not when the trigger function is actually
executed. One can disable or enable a single trigger specified by name, or all triggers on the
table, or only user triggers (this option excludes internally generated constraint triggers such as
those that are used to implement foreign key constraints or deferrable uniqueness and exclusion
constraints). Disabling or enabling internally generated constraint triggers requires superuser
privileges; it should be done with caution since of course the integrity of the constraint cannot
be guaranteed if the triggers are not executed. The trigger firing mechanism is also affected by
the configuration variable session_replication_role. Simply enabled triggers will fire when the
replication role is “origin” (the default) or “local”. Triggers configured as
ENABLE REPLICA

will only fire if the session is in “replica” mode, and triggers configured as
ENABLE ALWAYS
will fire regardless of the current replication mode.
This command acquires a
SHARE ROW EXCLUSIVE
lock

trigger_name
Name of a single trigger to disable or enable.
ALL
Disable or enable all triggers belonging to the table. (This requires superuser privilege if any of
the triggers are internally generated constraint triggers such as those that are used to implement
foreign key constraints or deferrable uniqueness and exclusion constraints.)
USER
Disable or enable all triggers belonging to the table except for internally generated constraint
triggers such as those that are used to implement foreign key constraints or deferrable uniqueness
and exclusion constraints


в принципе все понятно. Мне надо отключить триггер на одну транзакцию, затем включить его снова.
Я что боюсь: если я отключу триггер, в процессе выполнения транзакции кто-то будет менять данные в таблице паралельно со мной (начнет транзакцию свою позже, а затем завершит ее раньше) на него отключенный тригер не подействует? Я хочу чтобы на остальных отключенный триггер действовал .
Вот код:
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
CREATE TABLE a(x INT); -- рабочая таблица
CREATE TABLE logs.a(time TIMESTAMP, x INT); --таблица логов

CREATE OR REPLACE FUNCTION logs.a () RETURNS TRIGGER AS $$
DECLARE
VAL RECORD;
BEGIN
IF TG_OP = 'INSERT' THEN VAL := NEW; ELSE VAL := OLD; END IF;


INSERT  INTO logs.a (time, x)
SELECT  NOW(), VAL.x

RETURN CASE WHEN TG_OP = 'DELETE' THEN OLD ELSE NEW END; 
END;
$$ LANGUAGE plpgsql;	

CREATE  TRIGGER  log BEFORE
INSERT OR UPDATE OR DELETE
ON  a
FOR  EACH  ROW  EXECUTE  PROCEDURE  
logs.a ();


Надо отключить на 1 транзакцию триггер "log".

Подействует ли отключение на другие транзакции?
Код: sql
1.
2.
3.
ALTER TABLE a DISABLE TRIGGER log;
INSERT INTO a(x) VALUES (1), (2), (3);
ALTER TABLE ENABLE TRIGGER log;



Спасибо за ответы!!
--
Россия - отличная страна!
...
Рейтинг: 0 / 0
Всем привет! Поговорим про отключение триггеров
    #39760594
Фотография Maxim Boguk
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
PCContra,

После ALTER TABLE a DISABLE TRIGGER log; - никто ничего с этой таблицей сделать не сможет.
Она эксклюзивно заблокирована на вашу сессию.
С нее даже select из другой сессии не сделать не то что запись.

Кстати мог бы и сам проверить.
...
Рейтинг: 0 / 0
Всем привет! Поговорим про отключение триггеров
    #39760625
tunknown
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
PCContraНадо отключить на 1 транзакцию триггер "log".Можно создать отдельную таблицу, в которой для каждой сессии сделать настройку и эту настройку проверять в триггере, однако, это путь в никуда. Лучше сделать доступ к таблицам через хранимые процедуры. Если же у вас ORM, то уже ничего не поможет.
...
Рейтинг: 0 / 0
Всем привет! Поговорим про отключение триггеров
    #39762161
Garik888
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Я для таких случаев я сделал отдельное поле trigger_off
По дефолту оно равно нулю, но если я ставлю туда 1, то в триггере проверяю, если равно 1, то игнорирую всю работу триггера.
Но в этом варианте нужно в этом же триггере менять значение trigger_off всегда на 0
...
Рейтинг: 0 / 0
Всем привет! Поговорим про отключение триггеров
    #39762197
qwwq
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
не знаю , как нынче, а раньше в пж всегда можно было отальтерить тело триггерной функции на старте транзы, сделать тёмное, и вернуть тело ф-ии взад в конце. чем это теоретицки чревато с т.з. консистентностей и т.п., в т.ч. при смене уровней изоляции у конкурентов -- остаёцца догадываться. но работает. и много дешевле чем альтер триггер. к тому же тип активности триггера не меняется.
...
Рейтинг: 0 / 0
Всем привет! Поговорим про отключение триггеров
    #39762202
fte
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
А может вообще без альтеров
Код: plsql
1.
2.
3.
4.
if not pg_has_role(session_user,'__wo_trigger__','usage') then
    INSERT  INTO logs.a (time, x)
    SELECT  NOW(), VAL.x
end if
...
Рейтинг: 0 / 0
Всем привет! Поговорим про отключение триггеров
    #39762203
fte
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
fte,
Или лучше так:
Код: plsql
1.
2.
3.
4.
5.
6.
CREATE  TRIGGER  log BEFORE
INSERT OR UPDATE OR DELETE
ON  a
FOR  EACH  ROW  EXECUTE  PROCEDURE  
logs.a ()
WHEN (not pg_has_role(session_user,'__wo_trigger__','usage'));
...
Рейтинг: 0 / 0
Всем привет! Поговорим про отключение триггеров
    #39762239
Фотография Maxim Boguk
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
fte,

Тогда уж
set session_replication_role to 'replica';
и делай чего хочешь триггера не будут вызываться нормальные в этой сессии вообще ;).
...
Рейтинг: 0 / 0
Всем привет! Поговорим про отключение триггеров
    #39762295
256k
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Garik888Я для таких случаев я сделал отдельное поле trigger_off
По дефолту оно равно нулю, но если я ставлю туда 1, то в триггере проверяю, если равно 1, то игнорирую всю работу триггера.
Но в этом варианте нужно в этом же триггере менять значение trigger_off всегда на 0

хорошее решение, так можно самому себе сделать головняк
...
Рейтинг: 0 / 0
Всем привет! Поговорим про отключение триггеров
    #39762555
Garik888
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
256k хорошее решение, так можно самому себе сделать головняк
Интересно узнать, в чём именно головные? И чем решения с отключением триггера вообще являются НЕ головняком

Сказать по чесноку, желание отключить триггер это не правильно построенная структура базы и не верно построенная логика работы.
Да, бывают исключения которые возникают в процессе работы и мой вариант позволяет учитывать эту логику и контролировать её в случае необходимости. А что будет, если отключать триггер!?!? Это вообще противоречит нормальной работе СУБД!
...
Рейтинг: 0 / 0
Всем привет! Поговорим про отключение триггеров
    #39762731
gav21
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Maxim Boguk,
к сожалению не работает на truncate :(
так же как и alter table t2 disable trigger all;
...
Рейтинг: 0 / 0
Всем привет! Поговорим про отключение триггеров
    #39762827
Фотография Maxim Boguk
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
gav21Maxim Boguk,
к сожалению не работает на truncate :(
так же как и alter table t2 disable trigger all;

А можете минимальный тестовый пример составить и прислать? Или очень странно или баг.

--
Maxim Boguk
лучшая поддержка PostgreSQL: dataegret.ru
...
Рейтинг: 0 / 0
Всем привет! Поговорим про отключение триггеров
    #39762881
Melkij
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
gav21Maxim Boguk,
к сожалению не работает на truncate :(
так же как и alter table t2 disable trigger all;
Можете пояснить что именно "не работает на truncate"?
Проверил сейчас, after truncate trigger не вызывается как для session_replication_role=replica так и при disable trigger
...
Рейтинг: 0 / 0
Всем привет! Поговорим про отключение триггеров
    #39762893
gav21
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Melkij,
речь про truncate таблицы с внешним ключем:
postgres=# truncate table t1;
ERROR: cannot truncate a table referenced in a foreign key constraint
DETAIL: Table "t2" references "t1".
HINT: Truncate table "t2" at the same time, or use TRUNCATE ... CASCADE.
...
Рейтинг: 0 / 0
Всем привет! Поговорим про отключение триггеров
    #39762899
Melkij
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
gav21,

ну так и должно быть. Триггеры тут ни при чём. Это сам truncate проверяет зависимости.
...
Рейтинг: 0 / 0
Всем привет! Поговорим про отключение триггеров
    #39767356
PCContra
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Maxim BogukPCContra,

После ALTER TABLE a DISABLE TRIGGER log; - никто ничего с этой таблицей сделать не сможет.
Она эксклюзивно заблокирована на вашу сессию.
С нее даже select из другой сессии не сделать не то что запись.

Кстати мог бы и сам проверить.
SELECT делает. UPDATE нет (из под другой сессии). В таблицу логов (под другой сессией) добавилась 1 запись (как и нужно)

Как я тестировал:
Запустил
Код: sql
1.
2.
3.
ALTER TABLE a DISABLE TRIGGER log;
INSERT INTO a(x) VALUES (1), (2), (3);--делается порядка 14 секунд
ALTER TABLE ENABLE TRIGGER log;


Успел переключиться на другую вкладку (под приватным просмотром, сессия другая 100%). Изменил данные в той же таблице. Сравнил количесво строк до и после в таблице логов.

Если кто вообще гуру, то может разобраться почему select делает
...
Рейтинг: 0 / 0
Всем привет! Поговорим про отключение триггеров
    #39767357
Фотография Maxim Boguk
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
PCContraMaxim BogukPCContra,

После ALTER TABLE a DISABLE TRIGGER log; - никто ничего с этой таблицей сделать не сможет.
Она эксклюзивно заблокирована на вашу сессию.
С нее даже select из другой сессии не сделать не то что запись.

Кстати мог бы и сам проверить.
SELECT делает. UPDATE нет (из под другой сессии). В таблицу логов (под другой сессией) добавилась 1 запись (как и нужно)

Как я тестировал:
Запустил
Код: sql
1.
2.
3.
ALTER TABLE a DISABLE TRIGGER log;
INSERT INTO a(x) VALUES (1), (2), (3);--делается порядка 14 секунд
ALTER TABLE ENABLE TRIGGER log;


Успел переключиться на другую вкладку (под приватным просмотром, сессия другая 100%). Изменил данные в той же таблице. Сравнил количесво строк до и после в таблице логов.

Если кто вообще гуру, то может разобраться почему select делает

begin/commit Где? ("Мне надо отключить триггер на одну транзакцию, затем включить его снова." - вот куда вы тут транзакцию потеряли запрошенную).
без Begin/commit у вас каждый запрос - завершенная транзакция.
И вы отключили триггера на таблице не для себя а для всех таким образом.

--
Maxim Boguk
лучшая поддержка PostgreSQL: dataegret.ru
...
Рейтинг: 0 / 0
17 сообщений из 17, страница 1 из 1
Форумы / PostgreSQL [игнор отключен] [закрыт для гостей] / Всем привет! Поговорим про отключение триггеров
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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