Mise à jour de PostgreSQL 12 : il existe un support limité pour le niveau supérieur PROCEDURE
qui peuvent faire du contrôle de transaction . Il n'est toujours pas possible de gérer les transactions dans les fonctions normales appelables en SQL, de sorte que ce qui suit reste vrai, sauf en cas d'utilisation des nouvelles procédures de haut niveau.
Les fonctions font partie de la transaction à partir de laquelle elles sont appelées. Leurs effets sont annulés si la transaction est annulée. Leur travail est validé si la transaction est validée. Tout BEGIN ... EXCEPT
à l'intérieur de la fonction fonctionnent comme des points de sauvegarde (et les utilisent) comme la fonction SAVEPOINT
et ROLLBACK TO SAVEPOINT
Instructions SQL.
La fonction réussit dans son intégralité ou échoue dans son intégralité, à l'exception des cas suivants BEGIN ... EXCEPT
la gestion des erreurs. Si une erreur est soulevée dans la fonction et n'est pas traitée, la transaction qui appelle la fonction est interrompue. Les transactions interrompues ne peuvent pas valider, et si elles tentent de le faire, la fonction COMMIT
est traité comme ROLLBACK
comme pour toute autre transaction erronée. Observez :
regress=# BEGIN;
BEGIN
regress=# SELECT 1/0;
ERROR: division by zero
regress=# COMMIT;
ROLLBACK
Voyez comment la transaction, qui est dans l'état d'erreur en raison de la division par zéro, revient en arrière sur COMMIT
?
Si vous appelez une fonction sans une transaction explicite qui l'entoure, les règles sont exactement les mêmes que pour toute autre instruction Pg :
BEGIN;
SELECT refresh_materialized_view(name);
COMMIT;
(où COMMIT
échouera si le SELECT
a soulevé une erreur).
PostgreSQL ne supporte pas (encore) les transactions autonomes dans les fonctions, où la procédure/fonction pourrait commiter/reculer indépendamment de la transaction appelante. Ceci peut être simulé en utilisant une nouvelle session via dblink .
MAIS Les choses qui ne sont pas transactionnelles ou qui sont imparfaitement transactionnelles existent dans PostgreSQL. S'il a un comportement non-transactionnel dans un environnement normal, il est possible de le faire. BEGIN; do stuff; COMMIT;
il a un comportement non transactionnel dans une fonction également. Par exemple, nextval
et setval
, TRUNCATE
etc.