sql >> Base de Datos >  >> RDS >> PostgreSQL

¿Las funciones de PostgreSQL son transaccionales?

Actualización de PostgreSQL 12 :hay soporte limitado para PROCEDURE de nivel superior s que pueden hacer control de transacciones. Todavía no puede administrar transacciones en funciones regulares a las que se puede llamar SQL, por lo que lo siguiente sigue siendo cierto, excepto cuando se usan los nuevos procedimientos de nivel superior.

Las funciones son parte de la transacción desde la que se llaman. Sus efectos se revierten si la transacción se revierte. Su trabajo se compromete si la transacción se confirma. Cualquier BEGIN ... EXCEPT los bloques dentro de la función funcionan como (y debajo del capó usan) puntos de guardado como el SAVEPOINT y ROLLBACK TO SAVEPOINT Sentencias SQL.

La función tiene éxito en su totalidad o falla en su totalidad, excepto BEGIN ... EXCEPT manejo de errores. Si se genera un error dentro de la función y no se maneja, se aborta la transacción que llama a la función. Las transacciones anuladas no pueden confirmarse, y si intentan confirmarse, COMMIT se trata como ROLLBACK , igual que para cualquier otra transacción por error. Observa:

regress=# BEGIN;
BEGIN
regress=# SELECT 1/0;
ERROR:  division by zero
regress=# COMMIT;
ROLLBACK

Vea cómo la transacción, que está en estado de error debido a la división por cero, retrocede en COMMIT ?

Si llama a una función sin una transacción circundante explícita, las reglas son exactamente las mismas que para cualquier otra instrucción Pg:

BEGIN;
SELECT refresh_materialized_view(name);
COMMIT;

(donde COMMIT fallará si SELECT generó un error).

PostgreSQL (todavía) no admite transacciones autónomas en funciones, donde el procedimiento/función podría comprometerse/revertirse independientemente de la transacción de llamada. Esto se puede simular usando una nueva sesión a través de dblink.

PERO , las cosas que no son transaccionales o son imperfectamente transaccionales existen en PostgreSQL. Si tiene un comportamiento no transaccional en un BEGIN; do stuff; COMMIT; block, también tiene un comportamiento no transaccional en una función. Por ejemplo, nextval y setval , TRUNCATE , etc.