If a stored procedure fails in middle, are changes at that point from the beginning of SP rolled back implicitly or do we have to write any explicit code to make sure that SP runs in a database transaction only?

- 605,456
- 145
- 1,078
- 1,228

- 1,259
- 1
- 10
- 18
-
possible duplicate of [Execute postgreSQL stored procedure as one transaction](http://stackoverflow.com/questions/26406111/execute-postgresql-stored-procedure-as-one-transaction) – Mitch Wheat Jan 31 '15 at 10:05
-
2All covered in the manual. Including the fact that you don't technically have stored procedures in PostgreSQL – Richard Huxton Jan 31 '15 at 12:34
3 Answers
Strictly speaking, Postgres did not have stored procedures as defined in the ISO/IEC standard before version 11. The term is often used incorrectly to refer to functions, which provide much of the same functionality (and more) as other RDBMS provide with "stored procedures". The main difference being transaction handling.
True stored procedures were finally introduced with Postgres 11:
Functions are atomic in Postgres. They always run in a transaction context and succeed or fail completely. Consequently, one cannot begin or commit transactions within the function. And commands like VACUUM
, CREATE DATABASE
, or CREATE INDEX CONCURRENTLY
which do not run in a transaction context are not allowed.
Functions and trigger procedures are always executed within a transaction established by an outer query — they cannot start or commit that transaction, since there would be no context for them to execute in. However, a block containing an
EXCEPTION
clause effectively forms a subtransaction that can be rolled back without affecting the outer transaction.
By default, any error occurring in a PL/pgSQL function aborts execution of the function, and indeed of the surrounding transaction as well. You can trap errors and recover from them by using a
BEGIN
block with anEXCEPTION
clause.
There are exceptions, including but not limited to:
data written to log files
-
Important: Some PostgreSQL data types and functions have special rules regarding transactional behavior. In particular, changes made to a sequence (and therefore the counter of a column declared using
serial
) are immediately visible to all other transactions and are not rolled back if the transaction that made the changes aborts. prepared statements
SQL Fiddle demodblink calls (or similar)

- 605,456
- 145
- 1,078
- 1,228
If you are using Postgres 14 procedure like below:
CREATE OR REPLACE PROCEDURE test_error(schema_name text)
LANGUAGE plpgsql
AS
$$
declare
<declare any vars that you need>
BEGIN
<do your thing>
END
$$;
For all practical purposes, code written in between the BEGIN
and END
block is executed in a single transaction. Hence, if any of the statements in the block fail, all the previous statements will be rolled back automatically. You do not need to explicitly write any roll back code.
However, there are special cases where one can have fine grained control over when to start/commit/rollback transactions. Refer to : https://www.postgresql.org/docs/current/plpgsql-transactions.html for details.

- 5,239
- 1
- 43
- 24
From the official document of Postgresql:
In procedures invoked by the CALL command as well as in anonymous code blocks (DO command), it is possible to end transactions using the commands COMMIT and ROLLBACK. A new transaction is started automatically after a transaction is ended using these commands, so there is no separate START TRANSACTION command. (Note that BEGIN and END have different meanings in PL/pgSQL.)
https://www.postgresql.org/docs/11/plpgsql-transactions.html

- 12,262
- 10
- 69
- 70