Postgres prend en charge les transactions imbriquées, mais elles diffèrent du SQL conventionnel, plus comme des transactions avec des points partiels imbriqués.
Au niveau supérieur, vous avez toujours votre BEGIN/COMMIT/ROLLBACK
typique , et sur les niveaux imbriqués, vous devez utiliser les commandes suivantes :
SAVEPOINT name
- crée un nouveau point de sauvegarde, avec un nom unique pour la transactionRELEASE SAVEPOINT name
- valide le point de sauvegarde, bien qu'il ne persiste que si la transaction contenant est validéeROLLBACK TO SAVEPOINT name
- annule le point de sauvegarde
Vous devrez également vous assurer que :
- Les noms utilisés pour chaque
SAVEPOINT
sont uniques ; - Échec dans un
SAVEPOINT
est propagé vers le haut jusqu'au niveau supérieur.
Le dernier élément est un peu délicat, à moins que vous n'utilisiez une bibliothèque capable de le faire automatiquement pour vous.
Lorsque j'ai écrit pg-promise, je me suis assuré que ces deux dispositions sont garanties :
- Il génère automatiquement des noms de point de sauvegarde, comme
level_1
,level_2
, et ainsi de suite, en fonction du niveau de transaction ; - Il s'exécute en contenant
ROLLBACK TO SAVEPOINT name
, plus le niveau supérieurROLLBACK
en cas d'échec d'une transaction enfant - le tout basé sur la logique standard de chaînage de promesses.
Voir aussi les limitations des transactions imbriquées PostgreSQL expliquées...