Une nouvelle transaction démarre avec les caractéristiques de transaction
avec leurs valeurs par défaut, comme le niveau d'isolation.
Dans le cas où les transactions sont validées à l'intérieur d'une
boucle, on peut désirer qu'une transaction démarre automatiquement
avec les mêmes caractéristiques que la précédente. Les commandes
COMMIT AND CHAIN et ROLLBACK AND
CHAIN font cela.
Dans les procédures appelées par la commande CALL ainsi
que dans les blocs de code anonymes (commande DO), il
est possible de terminer les transactions en utilisant les commandes
COMMIT et ROLLBACK. Une nouvelle
transaction est démarrée automatiquement après qu'une transaction ait été
terminée en utilisant ces commandes, donc il n'existe pas de commande
START TRANSACTION. (Notez que BEGIN
et END ont une signification différente dans PL/pgSQL.)
Voici un exemple simple :
CREATE PROCEDURE transaction_test1()
LANGUAGE plpgsql
AS $$
BEGIN
FOR i IN 0..9 LOOP
INSERT INTO test1 (a) VALUES (i);
IF i % 2 = 0 THEN
COMMIT;
ELSE
ROLLBACK;
END IF;
END LOOP;
END
$$;
CALL transaction_test1();
Le contrôle des transactions est seulement possible dans les appels à
CALL et DO à partir du plus haut
niveau ou dans les appels imbriqués à CALL ou
DO sans autre commande. Par exemple, si la pile d'appel
est CALL proc1() → CALL proc2()
→ CALL proc3(), alors la deuxième et la troisième
procédures peuvent exécuter les actions de contrôle de transaction. Mais
si la pile d'appel est CALL proc1() →
SELECT func2() → CALL proc3(),
alors la dernière procédure ne peut pas faire de contrôle de transactions
à cause du SELECT.
Des considérations spéciales s'appliquent aux boucles de curseur. Considérez cet exemple :
CREATE PROCEDURE transaction_test2()
LANGUAGE plpgsql
AS $$
DECLARE
r RECORD;
BEGIN
FOR r IN SELECT * FROM test2 ORDER BY x LOOP
INSERT INTO test1 (a) VALUES (r.x);
COMMIT;
END LOOP;
END;
$$;
CALL transaction_test2();
Habituellement, les curseurs sont automatiquement fermés au moment de la
validation de la transaction. Néanmoins, un curseur créé dans une boucle
comme celle-ci est automatiquement converti en un curseur maintenable par
le premier COMMIT ou ROLLBACK. Ceci
signifie que le curseur est complètement évalué au premier
COMMIT ou ROLLBACK plutôt que ligne
par ligne. Le curseur est toujours automatiquement supprimé après la
boucle, donc c'est pratiquement invisible pour l'utilisateur.
Les commandes de transaction ne sont pas autorisées dans les boucles de
curseur exécutés par des commandes qui ne sont pas en lecture seule (par
exemple UPDATE ... RETURNING).
Une transaction ne peut pas être terminée dans un bloc contenant un gestionnaire d'exceptions.