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
SAVEPOINT
are unique; - Failure in one
SAVEPOINT
is 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
level_1
,level_2
, and so on, based on the transaction level; - It executes containing
ROLLBACK TO SAVEPOINT name
, plus the top-levelROLLBACK
in case a child transaction fails – all built on the standard promise-chaining logic.
See also the limitations of the PostgreSQL nested transactions explained…