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
.
PL/pgSQL n'accepte pas les commandes pour les
savepoints (SAVEPOINT
/ROLLBACK TO
SAVEPOINT
/RELEASE SAVEPOINT
). Les usages
typiques des savepoints peuvent être remplacés par des blocs d'exception
(voir Section 41.6.8). Dans les faits, un bloc
aves des gestionnaires d'exception forme une sous-transaction, ce qui signifie
que les transactions ne peuvent pas être terminées à l'intérieur d'un tel
bloc.
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. Mais il faut
garder en tête que tout verrou de table ou de ligne pris par le curseur
n'existera plus après le premier COMMIT
ou
ROLLBACK
.
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
).