Postgres ondersteunt geneste transacties, maar ze verschillen van de conventionele SQL, meer zoals transacties met geneste deelpunten.
Op het hoogste niveau heb je altijd je typische BEGIN/COMMIT/ROLLBACK
, en op geneste niveaus moet je de volgende commando's gebruiken:
SAVEPOINT name
- maakt een nieuw opslagpunt aan, met een unieke naam voor de transactieRELEASE SAVEPOINT name
- begaat het opslagpunt, hoewel het alleen blijft bestaan als de bevattende transactie zich commitROLLBACK TO SAVEPOINT name
- rolt het opslagpunt terug
U moet er ook voor zorgen dat:
- De namen die worden gebruikt voor elk
SAVEPOINT
zijn uniek; - Fout in één
SAVEPOINT
wordt naar boven gepropageerd naar het hoogste niveau.
Het laatste stukje is een beetje lastig, tenzij je een bibliotheek gebruikt die dat automatisch voor je kan doen.
Toen ik pg-promise schreef, zorgde ik ervoor dat die twee bepalingen gegarandeerd zijn:
- Het genereert automatisch namen van opslagpunten, zoals
level_1
,level_2
, enzovoort, op basis van het transactieniveau; - Het wordt uitgevoerd met
ROLLBACK TO SAVEPOINT name
, plus deROLLBACK
op het hoogste niveau in het geval dat een onderliggende transactie mislukt - allemaal gebouwd op de standaard logica van belofteketens.
Zie ook de beperkingen van de PostgreSQL geneste transacties uitgelegd...