Que comportamento o PostgreSQL exibiria se, por exemplo, o script abaixo fosse chamado
BEGIN;
SELECT * FROM foo;
INSERT INTO foo(name) VALUES ('bar');
BEGIN; <- The point of interest
END;
O PostgreSQL descartaria o segundo BEGIN
ou um commit seria decidido implicitamente e então executaria o BEGIN
END
bloco no final como uma transação separada?
O que você precisa é de uma chamada "transação autônoma" (um recurso fornecido pela oracle). Neste ponto, isso ainda não é possível no PostgreSQL. No entanto, você pode usar SAVEPOINT s:
Não é totalmente uma transação autônoma - mas permite que você acerte "todas as transações". Você pode usá-lo para obter o que espera de transações autônomas.
Caso contrário, não há outra solução razoável neste momento.
Você pode tentar você mesmo:
Ele não inicia nenhuma nova (sub)transação, pois as transações aninhadas não são implementadas no PostgreSQL. (Você pode fazer alguma mágica em uma
pl/pgsql
função, por exemplo, que imita esse comportamento.)Com o PostgreSQL 11, pode-se pensar que os novos procedimentos armazenados reais e sua capacidade de lidar com transações tornariam as transações aninhadas possíveis. No entanto, de acordo com a documentação , este não é o caso:
O PostgreSQL não oferece suporte a subtransações, mas o
SAVEPOINT
recurso pode atender efetivamente à sua necessidade. Citando a documentação da camada de acesso avançado ao PG por meio de promessas de Vitaly Tomilov no GitHub:Os pontos de salvamento podem ser usados para reversões parciais para um ponto anterior dentro de uma transação ativa. Por exemplo, para estabelecer um savepoint e depois desfazer os efeitos de todos os comandos executados depois de estabelecido:
A transação acima irá inserir os valores 1 e 3, mas não 2. Consulte a
SAVEPOINT
documentação para mais informações.Para o Postgresql 9.5 ou mais recente, você pode usar trabalhadores dinâmicos em segundo plano fornecidos pela extensão pg_background. Ele cria uma transação autônoma. Por favor, consulte a página do github da extensão. A solução é melhor que db_link. Existe um guia completo sobre suporte a transações autônomas no PostgreSQL