Postgres does support nested transactions, but they differ from the conventional SQL, more like transactions with nested partial points.
On the top level you always have your typical BEGIN/COMMIT/ROLLBACK, and on nested levels you have to use the following commands:
SAVEPOINT name– creates a new savepoint, with name unique for the transactionRELEASE SAVEPOINT name– commits the savepoint, though it will only persist if the containing transaction commitsROLLBACK TO SAVEPOINT name– rolls back the savepoint
You would also have to make sure that:
- The names used for each
SAVEPOINTare unique; - Failure in one
SAVEPOINTis propagated upwards to the top level.
The last bit is a bit tricky, unless you use a library that can do that for you automatically.
When I wrote pg-promise, I made sure that those two provisions are guaranteed:
- It generates save-point names automatically, as
sp_xy, wherexis the current task/transaction depth, andyis the actual transaction level + 1; - It executes containing
ROLLBACK TO SAVEPOINT name, plus the top-levelROLLBACKin case a child transaction fails – all built on the standard promise-chaining logic.
See also the limitations of the PostgreSQL nested transactions explained…