PostgreSQL: откат транзакции в функции plpgsql?

Исходя из мира MS SQL, я стараюсь активно использовать хранимые процедуры. В настоящее время я пишу приложение, использующее множество функций PostgreSQL plpgsql. То, что я хотел бы сделать, - откат всех INSERTS/UPDATES, содержащихся в определенной функции, если я получаю исключение в любой точке внутри него.

Первоначально у меня создалось впечатление, что каждая функция заверяется в свою собственную транзакцию и что исключение автоматически откатывает все. Однако, похоже, это не так. Мне интересно, если я должен использовать точки сохранения в сочетании с обработкой исключений? Но я не понимаю разницу между транзакцией и точкой сохранения, чтобы знать, подходит ли это наилучший подход. Любые советы, пожалуйста?

CREATE OR REPLACE FUNCTION do_something(
         _an_input_var int
                ) RETURNS bool AS $$
        DECLARE
                _a_variable int;
        BEGIN
                INSERT INTO tableA (col1, col2, col3)
                        VALUES (0, 1, 2);

                INSERT INTO tableB (col1, col2, col3)
                        VALUES (0, 1, 'whoops! not an integer');

                -- The exception will cause the function to bomb, but the values 
                -- inserted into "tableA" are not rolled back.    

                RETURN True;
END; $$ LANGUAGE plpgsql;

Ответ 1

Функция выполняет транзакцию. Вам не нужно обертывать функцию в BEGIN/COMMIT.

Ответ 2

Вы не можете использовать команду фиксации или отката в функции, но вы можете использовать свою функцию в транзакции с фиксацией,

НАЧАТЬ ПЕРЕДАЧУ; SELECT do_something(); COMMIT;

Этот SQL script регистрируется только в том случае, если в do_something нет исключений, тогда он откатит транзакцию функции.

Ответ 3

docs сказать это:

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

Они также приводят примеры.

Edit:

Вам нужно обернуть transaction в командах BEGIN и COMMIT.

транзакция настраивается путем окружения команд SQL транзакции командами BEGIN и COMMIT

Ответ 4

Сохраняющие точки могут использоваться для эмуляции вложенных транзакций. Поскольку postgresql-транзакция представляет собой последовательность операторов, которые будут применены или отброшены, точки сохранения могут отмечать точки в пределах этой последовательности, которые позволяют вернуться назад.

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