transações aninhadas no PostgreSQL 8.2?
-
03-07-2019 - |
Pergunta
Eu estou trabalhando em scripts que apliquem as atualizações de esquema de banco de dados. Eu setup todos os meus scripts de atualização SQL usando a transação start / commit. Eu passar esses scripts para psql na linha de comando.
Agora eu preciso aplicar vários scripts ao mesmo tempo, e em uma transação. Até agora, a única solução que eu vim acima com é remover a transação start / comprometer a partir do conjunto original de roteiros, em seguida, jam-los juntos dentro de uma nova transação start / comprometer bloco. Eu estou escrevendo scripts perl para fazer isso em tempo real.
Efetivamente eu quero transações aninhadas, o que eu não consigo descobrir como fazer no PostgreSQL.
Existe alguma maneira de fazer ou transações aninhadas simulados para este fim? Tenho a configuração de coisas para automaticamente salvar em qualquer erro, então eu não preciso de continuar na transação nível superior se qualquer um dos mais baixos falhar.
Solução
Bem, você tem a possibilidade de usar transações aninhadas dentro do PostgreSQL usando pontos de salvamento.
Veja este exemplo de código:
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)
Talvez isso vai ajudá-lo um pouco.
Outras dicas
Eu acabei 'resolver' o meu problema fora da banda - eu uso um script Perl para re-trabalho os scripts de entrada para eliminar a sua transação start / comprometer chamadas, em seguida, empurre-los todos em um único arquivo, que recebe o seu próprio iniciar a transação / commit.