Приезжая из мира SQL MS, я склонен делать интенсивное использование хранимых процедур. Я в настоящее время пишу, что приложение использует много функций PostgreSQL plpgsql. То, что я хотел бы сделать, откатывать, все ВСТАВЛЯЕТ/ОБНОВЛЯЕТ содержавший в конкретной функции, если я получаю исключение в какой-либо точке в ней.
У меня первоначально создалось впечатление, что каждая функция перенесена в свою собственную транзакцию и что исключение автоматически откатывало бы все. Однако это, кажется, не имеет место. Я задаюсь вопросом, должен ли я использовать точки сохранения в сочетании с обработкой исключений вместо этого? Но я действительно не понимаю различия между транзакцией и точкой сохранения, чтобы знать, является ли это лучшим подходом. Совет?
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;
Функция представляет собой транзакцию. Вы не обязаны обертывать функцию в BEGIN/COMMIT.
Точки сохранения можно использовать для эмуляции вложенных транзакций. Поскольку транзакция postgresql - это последовательность утверждений, которые будут либо применены, либо отброшены, точки сохранения могут отмечать точки в этой последовательности, к которым можно вернуться.
Поскольку настоящие вложенные транзакции не поддерживаются, это лучший вариант (и очень хороший).
В документах говорится следующее:
Точка сохранения - это специальная метка внутри транзакции, которая позволяет всем команды, которые выполняются после того, как была установлена возможность отката, восстанавливая состояние транзакции до того, что было во время точки сохранения.
Они тоже приводят примеры.
Изменить:
Вам необходимо заключить транзакцию в команды BEGIN и COMMIT.
транзакция устанавливается путем окружения команд SQL транзакции командами BEGIN и COMMIT