у меня есть 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
Оператор не вернется, пока функция триггера не завершится.
Я бы поместил задания, которые занимают много времени, в таблицу «очередь» и имеет отдельный процесс, который асинхронно обрабатывает задания в очереди. Таким образом, вам не нужно беспокоиться о тайм-аутах.
Для связи между процессами вы можете либо регулярно получать статус, либо использовать PostgreSQL. LISTEN
а также NOTIFY
,
Я на 90% уверен, что вам придется дождаться окончания триггера, чтобы получить идентификатор, поэтому время ожидания будет снова.
Таким образом, в этом случае вы должны получить идентификатор (как вы говорите, почти мгновенно), а затем сделать второй вызов процедуры сохранения с использованием идентификатора