While some database engines allow COMMIT
or ROLLBACK
inside a function or procedure, PostgreSQL does not. Any attempt to do that leads to an error:
ERROR: cannot begin/end transactions in PL/pgSQL
That includes code inside an exception block.
On the other hand, a RAISE EXCEPTION
alone will abort the transaction with the function-supplied error message, so there's no need to trap your own exception. It would work as expected if you just removed your exception block.
As said by the plpgsql documentation in Trapping Errors:
By default, any error occurring in a PL/pgSQL function aborts execution of the function, and indeed of the surrounding transaction as well
You current code raises the exception, then traps it and fails in the exception block itself because of the forbidden ROLLBACK
statement, which leads to the SQL engine aborting the transaction.