I’m studying Postgres by reading the docs, and section 3.4 says this:
"Keep in mind that either releasing or rolling back to a savepoint will automatically release all savepoints that were defined after it.
https://postgresql.org/docs/current/tutorial-transactions.html
Surely they mean "will automatically release OR ROLLBACK all savepoints"?
It would make no sense to release (which means commit) a savepoint that you’re rolling back past, right?
2
Answers
Releasing a savepoint does not alter table data nor does it undo any work that is part of the current transaction: it just discards the information necessary to
ROLLBACK
to that savepoint. Any savepoints that were created after the released savepoint are also released.Performing a
ROLLBACK TO SAVEPOINT
effectively restores the current transaction to the state that existed when the savepoint was defined; therefore, savepoints that were created after theROLLBACK
savepoint are released because the transaction is no longer capable of restoring the state of those savepoints.Performing a
COMMIT
releases all savepoints.They don’t mean
rollback
as that would undo whatever happened in between the later savepoints, which it does not when you justrelease
an earlier savepoint.The idea that
release
is a "subtransaction commit" is at least an oversimplification. You don’t really need to release savepoints to have their changes contribute to the transaction. Releasing a savepoint means you just no longer need the option to go that far back in time, which implies you also no longer need to be able to go any less back in time than that.If you’re satisfied with the work you’ve been doing for the past hour, it’s understood that you’re also ok with what you did 15 or 20 minutes ago. Undoing the past hour, also undoes stuff from 15 minutes ago.
Automatically releasing the in-between savepoints makes sense: you can’t
rollback
forward to a savepoint you just went past. Why keep it?Consider this: demo at db<>fiddle
Once you went back to
s1
, arollback to savepoint s2
would mean going forward:s1
and instead re-do what you had done originally.s2
operations on top of what you just did.There are ways either of these could be implemented, but currently that only works in one direction, and undoing an undo just requires a re-do.