Написать сообщение об исключении в таблицу - PullRequest
0 голосов
/ 18 июня 2019

У меня есть следующая функция, которая вызывается веб-API для импорта некоторых загруженных данных. Существует также таблица upload_log, в которой хранится состояние загрузки и которая может быть обработана API.

Мой вопрос относится к управлению транзакциями Postgresql: я знаю, что все между BEGIN...END блоками - это транзакции в PG и что он автоматически откатывается, как только одна инструкция завершается неудачей.

Следовательно, исключение не должно записываться в таблицу upload_log, не так ли?

Тем не менее, я получаю сообщения об ошибках в своем upload_log и спрашиваю себя, почему это происходит.

  • Это из-за вызова вложенной функции PERFORM...?
  • Это из-за EXCEPTION WHEN OTHERS..., который позволяет записывать что-то в таблицу впоследствии?
  • Должен ли я явно вызывать ROLLBACK в блоке EXCEPTION?
  • Должен ли я написать свой upload_log с DBLink как «автономную транзакцию»

    CREATE OR REPLACE FUNCTION finalize_upload(sync_id in varchar)
    RETURNS void AS $$
    DECLARE
       vCount numeric;
       err1 text;
       err2 text;
       err3 text;
    BEGIN
       -- Mark as Upload in Progress
       update upload_log
       set
          sync_status='1'
       where
          upload_log.gto_sync_id=finalize_upload.sync_id;

       begin
          vCount := 1;

          -- do some heavy stuff
          -- move data from import tables into production
          perform finalize_upload_specific(finalize_upload.sync_id);

       exception when others then
          GET STACKED DIAGNOSTICS err1 = MESSAGE_TEXT,
                            err2 = PG_EXCEPTION_DETAIL,
                            err3 = PG_EXCEPTION_HINT;

          -- Mark Upload as failed
          update upload_log
          set
             END_DATE=current_timestamp,
             sync_status='-1',
             err_hint=err1||' '||err2||' '||err3
          where
             upload_log.sync_id=finalize_upload.sync_id;
       end
       ;
    END
    $$ LANGUAGE plpgsql;

1 Ответ

1 голос
/ 18 июня 2019

Все между BEGIN и связанным EXCEPTION в блоке PL / pgSQL будет выполнено в субтранзакции.

Если выброшено какое-либо из обработанных исключений, субтранзакция откатывается, новключающая транзакция продолжается.UPDATE в обработчике исключений будет зафиксирован, потому что он уже находится за пределами субтранзакции, для которой выполняется откат.

Чтобы проиллюстрировать это с помощью псевдокода и точек сохранения SQL:

START TRANSACTION;
UPDATE upload_log SET sync_status='1' ...;
SAVEPOINT a;
SELECT finalize_upload_specific($1);
-- if an exception was thrown:
ROLLBACK TO SAVEPOINT a;
RELEASE SAVEPOINT a;
UPDATE upload_log SET sync_status='-1' ...;
COMMIT;
-- else
ROLLBACK;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...