В PostgreSQL запускаются триггеры DEFERRED до (внутри) завершения транзакции или сразу после нее?
В документации говорится:
DEFERRABLE
NOT DEFERRABLE
Это определяет, можно ли отложить ограничение. Ограничение то есть не откладывается, будет проверяться сразу после каждого команда. Проверка ограничений, которые откладываются, может быть отложена до конца транзакции (используя команду
SET CONSTRAINTS
).
Он не указывает, находится ли он внутри транзакции или отсутствует. Мой личный опыт говорит, что он находится внутри транзакции, и мне нужно, чтобы он был снаружи!
Выполняются ли три транзакции DEFERRED
(или INITIALLY DEFERRED
) внутри транзакции? И если да, то как я могу отложить их выполнение до момента завершения транзакции?
Чтобы дать вам подсказку, что мне нужно, я использую pg_notify
и RabbitMQ (PostgreSQL LISTEN Exchange) для отправки Сообщения. Я обрабатываю такие сообщения во внешнем приложении. Прямо сейчас у меня есть триггер, который уведомляет внешнее приложение вновь вставленных записей, включая идентификатор записи в сообщении. Но не детерминированным способом, время от времени, когда я пытаюсь выбрать запись по ее идентификатору, запись не может быть найдена. Это потому, что транзакция еще не завершена, и запись фактически не добавляется в таблицу. Если я могу только отложить выполнение триггера после завершения транзакции, все будет работать.
Чтобы получить более качественные ответы, позвольте мне объяснить ситуацию еще ближе к реальному миру. Фактический сценарий немного сложнее, чем я объяснял ранее. Исходный код можно найти здесь, если кому-то это интересно. Не имея причин, по которым я не собираюсь входить, мне нужно отправить уведомление из другой базы данных, чтобы уведомление было отправлено, например:
PERFORM * FROM dblink('hq','SELECT pg_notify(''' || channel || ''', ''' || payload || ''')');
Я уверен, что ситуация намного сложнее.