PostgreSQL 12 update: there is limited support for top-level
PROCEDUREs that can do transaction control. You still cannot manage transactions in regular SQL-callable functions, so the below remains true except when using the new top-level procedures.
Functions are part of the transaction they’re called from. Their effects are rolled back if the transaction rolls back. Their work commits if the transaction commits. Any
BEGIN ... EXCEPT blocks within the function operate like (and under the hood use) savepoints like the
ROLLBACK TO SAVEPOINT SQL statements.
The function either succeeds in its entirety or fails in its entirety, barring
BEGIN ... EXCEPT error handling. If an error is raised within the function and not handled, the transaction calling the function is aborted. Aborted transactions cannot commit, and if they try to commit the
COMMIT is treated as
ROLLBACK, same as for any other transaction in error. Observe:
regress=# BEGIN; BEGIN regress=# SELECT 1/0; ERROR: division by zero regress=# COMMIT; ROLLBACK
See how the transaction, which is in the error state due to the zero division, rolls back on
If you call a function without an explicit surounding transaction the rules are exactly the same as for any other Pg statement:
BEGIN; SELECT refresh_materialized_view(name); COMMIT;
COMMIT will fail if the
SELECT raised an error).
PostgreSQL does not (yet) support autonomous transactions in functions, where the procedure/function could commit/rollback independently of the calling transaction. This can be simulated using a new session via dblink.
BUT, things that aren’t transactional or are imperfectly transactional exist in PostgreSQL. If it has non-transactional behaviour in a normal
BEGIN; do stuff; COMMIT; block, it has non-transactional behaviour in a function too. For example,