PostgreSQL cannot begin/end transactions in PL/pgSQL PostgreSQL cannot begin/end transactions in PL/pgSQL postgresql postgresql

PostgreSQL cannot begin/end transactions in PL/pgSQL


A plpgsql function automatically runs inside a transaction. It all succeeds or it all fails. The manual:

Functions and trigger procedures are always executed within atransaction established by an outer query — they cannot start orcommit that transaction, since there would be no context for them toexecute in. However, a block containing an EXCEPTION clauseeffectively forms a subtransaction that can be rolled back withoutaffecting the outer transaction. For more about that see Section 42.6.6.

So, if you need to, you can catch an exception that theoretically might occur (but is very unlikely).
Details on trapping errors in the manual.

Your function reviewed and simplified:

CREATE FUNCTION foo(v_weather text                  , v_timeofday text                  , v_speed text                  , v_behavior text)  RETURNS SETOF custombehavior  LANGUAGE plpgsql AS$func$BEGINDELETE FROM custombehaviorWHERE  weather = 'RAIN'AND    timeofday = 'NIGHT'AND    speed = '45MPH';INSERT INTO custombehavior (weather, timeofday, speed, behavior)SELECT v_weather, v_timeofday, v_speed, v_behaviorWHERE  NOT EXISTS (   SELECT FROM defaultbehavior   WHERE  a = 'RAIN'   AND    b = 'NIGHT'   AND    c = '45MPH'   );RETURN QUERYSELECT * FROM custombehavior WHERE ... ;END$func$;

If you actually need to begin/end transactions like indicated in the title look to SQL procedures in Postgres 11 or later (CREATE PROCEDURE). See:


START TRANSACTION;select foo() ;COMMIT;

"Unfortunately Postgres has no stored procedures, so you always need to manage the transaction in the calling code" – a_horse_with_no_name

Transaction in an exception block - how?