Я работаю над сценариями, которые применяют обновления схемы базы данных. Я настроил все свои сценарии обновления SQL, используя start transaction / commit. Я передаю эти сценарии в psql из командной строки.
Теперь мне нужно применить несколько скриптов одновременно и за одну транзакцию. Пока что единственное решение, которое я придумал, - это удалить стартовую транзакцию / фиксацию из исходного набора скриптов, а затем объединить их в новый блок стартовой транзакции / фиксации. Я пишу Perl-скрипты, чтобы делать это на лету.
По сути, мне нужны вложенные транзакции, которые я не могу понять, как это сделать в postgresql.
Есть ли способ выполнять или моделировать вложенные транзакции для этой цели? У меня есть настройки для автоматического выхода из строя при любой ошибке, поэтому мне не нужно продолжать транзакцию верхнего уровня, если какая-либо из нижних не удалась.


Что ж, у вас есть возможность использовать вложенные транзакции внутри postgresql с помощью SavePoints.
Возьмите этот пример кода:
CREATE TABLE t1 (a integer PRIMARY KEY);
CREATE FUNCTION test_exception() RETURNS boolean LANGUAGE plpgsql AS
$$BEGIN
INSERT INTO t1 (a) VALUES (1);
INSERT INTO t1 (a) VALUES (2);
INSERT INTO t1 (a) VALUES (1);
INSERT INTO t1 (a) VALUES (3);
RETURN TRUE;
EXCEPTION
WHEN integrity_constraint_violation THEN
RAISE NOTICE 'Rollback to savepoint';
RETURN FALSE;
END;$$;
BEGIN;
SELECT test_exception();
NOTICE: Rollback to savepoint
test_exception
----------------
f
(1 row)
COMMIT;
SELECT count(*) FROM t1;
count
-------
0
(1 row)
Может быть, это вам немного поможет.
В итоге я решил «нестандартно» свою проблему - я использую Perl-скрипт, чтобы переработать входные скрипты, чтобы исключить их вызовы стартовой транзакции / фиксации, а затем помещаю их все в один файл, который получает свою собственную стартовую транзакцию / совершить.
Чтобы использовать точки сохранения в этом случае, мне пришлось бы изменить мои существующие сценарии и то, как они запускаются. В этом конкретном случае, если бы я собирался это сделать, я бы просто удалил блок начальной / конечной транзакции из всех моих скриптов и добавил его по отдельности, что упростило бы выполнение нескольких одновременно. Спасибо!