Триггерная функция PostgreSQL слишком долго приводит к таймауту php

проблема

у меня есть plpgsql функция prepare_download_file который передается в нескольких пользовательских параметров из php скрипт, вставляет эти параметры в таблицу журнала adc_query_log а затем использует их для создания sql запрос, который выбирает кучу данных, копирует результаты в csv и, наконец, возвращает уникальный идентификатор, который необходим в php скрипт. id является важной частью, так как php Сценарий использует его, чтобы выбрать 3 выходных файла, упаковать их в .zip архив, и отправьте электронное письмо пользователю со ссылкой для скачивания.

В зависимости от параметров запрос может выполняться довольно быстро, в других случаях я обнаружил, что это занимает более 45 секунд и время ожидания до php скрипт обеспокоен тем, что он не получает уникальный идентификатор, который ему нужен.

Предложенное решение

Разделить prepare_download_file Функция состоит из двух частей, так что первая часть только вставляет параметры в таблицу журнала и возвращает уникальный идентификатор, что должно происходить мгновенно (первый столбец id это тип serial):

INSERT INTO adc_query_log
VALUES (DEFAULT,query_type,severity,year_range,local_authorities)
RETURNING id INTO session_id;

Вторая часть make_download_file() выполняется через функцию триггера и возвращает NULL:

CREATE TRIGGER make_download_file AFTER INSERT ON adc_query_log
FOR EACH ROW EXECUTE PROCEDURE make_download_file();

который читает вставленные значения из таблицы, чтобы построить sql запрос, а затем выполняет всю тяжелую работу — предположительно, после того, как уникальный идентификатор был возвращен php скрипт.

Вопрос

Ли RETURNING id INTO session_id Подождите, пока функция триггера не завершится, прежде чем пометить эту транзакцию как завершенную и затем вернуть id? Если нет, то есть ли способ заставить его не ждать?

Сервер работает PostgreSQL 8.4

0

Решение

Оператор не вернется, пока функция триггера не завершится.

Я бы поместил задания, которые занимают много времени, в таблицу «очередь» и имеет отдельный процесс, который асинхронно обрабатывает задания в очереди. Таким образом, вам не нужно беспокоиться о тайм-аутах.

Для связи между процессами вы можете либо регулярно получать статус, либо использовать PostgreSQL. LISTEN а также NOTIFY,

1

Другие решения

Я на 90% уверен, что вам придется дождаться окончания триггера, чтобы получить идентификатор, поэтому время ожидания будет снова.

Таким образом, в этом случае вы должны получить идентификатор (как вы говорите, почти мгновенно), а затем сделать второй вызов процедуры сохранения с использованием идентификатора

0

По вопросам рекламы [email protected]