ROLLBACK_TO_SAVEPOINT(7)

โœจ ROLLBACK TO SAVEPOINT โœจ

ok so bestie, this is the PostgreSQL 18.6 Documentation page for ROLLBACK TO SAVEPOINT(7) and it's literally the "undo button but make it surgical" of the SQL world ๐Ÿ’…


๐ŸŒธ NAME ๐ŸŒธ

ROLLBACK_TO_SAVEPOINT โ€” roll back to a savepoint ๐ŸŽ€


๐Ÿฆ‹ SYNOPSIS ๐Ÿฆ‹

ROLLBACK [ WORK | TRANSACTION ] TO [ SAVEPOINT ] savepoint_name

๐Ÿ’– DESCRIPTION ๐Ÿ’–

okay so here's the tea โ˜• โ€” this command rolls back all the commands that were executed after the savepoint was established, and then it starts a brand new subtransaction at the same transaction level. it's giving "rewind, but we're still standing" โœจ

and the best part? the savepoint remains valid and you can roll back to it again later if you need to. it's not a one-time thing, it's a forever safe space ๐Ÿซถ

but heads up: ROLLBACK TO SAVEPOINT implicitly destroys all savepoints that were established after the named savepoint. no cap. they're gone, bestie ๐Ÿ’€


๐ŸŽ€ PARAMETERS ๐ŸŽ€

  • savepoint_name โ€” the savepoint you're rolling back to. that's it, that's the whole parameter ๐Ÿ“

๐ŸŒˆ NOTES ๐ŸŒˆ

  • use RELEASE SAVEPOINT when you wanna destroy a savepoint without discarding the effects of the commands executed after it was established. different vibe, different purpose, iykyk โœจ
  • specifying a savepoint name that has not been established is an error. it's not gonna be like "sure bestie, close enough" โ€” it's gonna yell at you ๐Ÿ˜ญ
  • cursors have somewhat non-transactional behavior with respect to savepoints, and honestly this is the part everyone gets confused about, so listen up ๐Ÿ‘‘:
    • any cursor that is opened inside a savepoint will be closed when the savepoint is rolled back.
    • if a previously opened cursor is affected by a FETCH or MOVE command inside a savepoint that is later rolled back, the cursor remains at the position that FETCH left it pointing to. translation: the cursor motion caused by FETCH is not rolled back. it justโ€ฆ stays. main character energy, refuses to be undone ๐Ÿ’…
    • closing a cursor is not undone by rolling back either. nope.
    • however, other side-effects caused by the cursor's query (like side-effects of volatile functions called by the query) are rolled back if they occur during a savepoint that is later rolled back. so it's a whole mix, bestie ๐Ÿฆ‹
    • a cursor whose execution causes a transaction to abort is put in a cannot-execute state, so while the transaction can be restored using ROLLBACK TO SAVEPOINT, the cursor can no longer be used. rip cursor ๐Ÿชฆ

โœจ EXAMPLES โœจ

want to undo the effects of the commands executed after my_savepoint was established? say less:

ROLLBACK TO SAVEPOINT my_savepoint;

and here's the iconic one showing that cursor positions are not affected by savepoint rollback โ€” watch the number change from 1 to 2 after the rollback, because the FETCH motion literally does not get undone ๐Ÿ˜ญ๐Ÿ”ฅ

BEGIN;

DECLARE foo CURSOR FOR SELECT 1 UNION SELECT 2;

SAVEPOINT foo;

FETCH 1 FROM foo;
 ?column?
----------
        1

ROLLBACK TO SAVEPOINT foo;

FETCH 1 FROM foo;
 ?column?
----------
        2

COMMIT;

๐Ÿ’œ COMPATIBILITY ๐Ÿ’œ

ok so the SQL standard says the key word SAVEPOINT is mandatory, but PostgreSQL and Oracle are the chill ones and allow it to be omitted ๐Ÿซถ

SQL also allows only WORK, not TRANSACTION, as a noise word after ROLLBACK. noted ๐Ÿ“

and SQL has an optional clause AND [ NO ] CHAIN which is not currently supported by PostgreSQL. so don't try it, bestie ๐Ÿ’€

otherwise? this command conforms to the SQL standard. slay ๐Ÿ‘‘


๐ŸŒŸ SEE ALSO ๐ŸŒŸ


and that's the whole page, babe ๐ŸŽ€ this was ROLLBACK TO SAVEPOINT(7) from the PostgreSQL 18.6 docs, dated 2026 โ€” go forth and roll back responsibly, you absolute icon ๐Ÿ‘‘๐Ÿ’–โœจ