PostgreSQL
 sql >> Base de données >  >> RDS >> PostgreSQL

Les fonctions PostgreSQL sont-elles transactionnelles ?

Mise à jour PostgreSQL 12  :la prise en charge de la PROCEDURE de niveau supérieur est limitée s qui peut faire le contrôle des transactions. Vous ne pouvez toujours pas gérer les transactions dans les fonctions appelables SQL standard, donc ce qui suit reste vrai sauf lors de l'utilisation des nouvelles procédures de niveau supérieur.

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 les blocs dans la fonction fonctionnent comme (et sous le capot utilisent) des points de sauvegarde comme le SAVEPOINT et ROLLBACK TO SAVEPOINT Instructions SQL.

La fonction réussit dans son intégralité ou échoue dans son intégralité, sauf BEGIN ... EXCEPT la gestion des erreurs. Si une erreur est déclenchée dans la fonction et n'est pas gérée, la transaction appelant la fonction est abandonnée. Les transactions abandonnées ne peuvent pas être validées, et si elles tentent de valider le COMMIT est traité comme ROLLBACK , comme pour toute autre transaction erronée. Observe :

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, est annulée sur COMMIT ?

Si vous appelez une fonction sans transaction explicite, 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 généré une erreur).

PostgreSQL ne prend pas (encore) en charge les transactions autonomes dans les fonctions, où la procédure/fonction pourrait valider/annuler indépendamment de la transaction appelante. Cela peut être simulé en utilisant une nouvelle session via dblink.

MAIS , des éléments non transactionnels ou imparfaitement transactionnels existent dans PostgreSQL. S'il a un comportement non transactionnel dans un BEGIN; do stuff; COMMIT; block, il a également un comportement non transactionnel dans une fonction. Par exemple, nextval et setval , TRUNCATE , etc.