O Postgres suporta transações aninhadas, mas elas diferem do SQL convencional, mais como transações com pontos parciais aninhados.
No nível superior, você sempre tem seu típico
BEGIN/COMMIT/ROLLBACK , e em níveis aninhados você deve usar os seguintes comandos:SAVEPOINT name- cria um novo ponto de salvamento, com nome exclusivo para a transaçãoRELEASE SAVEPOINT name- confirma o ponto de salvamento, embora ele só persista se a transação que a contém for confirmadaROLLBACK TO SAVEPOINT name- reverte o ponto de salvamento
Você também teria que se certificar de que:
- Os nomes usados para cada
SAVEPOINTsão únicos; - Falha em um
SAVEPOINTé propagado para cima até o nível superior.
A última parte é um pouco complicada, a menos que você use uma biblioteca que possa fazer isso automaticamente.
Quando escrevi pg-promise, certifiquei-me de que essas duas cláusulas fossem garantidas:
- Ele gera nomes de pontos de salvamento automaticamente, como
level_1,level_2, e assim por diante, com base no nível da transação; - Executa contendo
ROLLBACK TO SAVEPOINT name, mais oROLLBACKde nível superior caso uma transação filha falhe - tudo baseado na lógica de cadeia de promessas padrão.
Veja também as limitações das transações aninhadas do PostgreSQL explicadas...