Transaction en erreur sur CLOSE ou INSERT

From: philippe(dot)beaudoin(at)bull(dot)net
To: pgsql-fr-generale(at)postgresql(dot)org
Subject: Transaction en erreur sur CLOSE ou INSERT
Date: 2009-01-10 09:41:57
Message-ID: OF7FDC5B1E.BD8DDED5-ONC125753A.00320617@frcl.bull.fr
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-fr-generale

Bonjour à tous, et que cette nouvelle année vous soit douce...

La migration vers PostgreSQL d'une très grosse application sur laquelle
j'assiste un client me pose 2 problèmes qui ne sont pas sans rapport.

1) CLOSE curseurs préventifs

L 'application, très modulaire, concentre les accès aux données dans des
programme C qui utilisent de nombreux curseurs. Pour certains d'entre eux,
il y a un CLOSE curseur codé avant l'OPEN, afin de s'assurer que le curseur
est bien fermé (il n'est pas toujours aisé de savoir si un autre programme
aurait ou non effectué un COMMIT).
Avec les SGBD actuellement utilisés par ce client (DB2 sur Z-OS et RFM-II
sur GCOS 8), si le curseur n'est pas ouvert, le CLOSE retourne un SQLCODE
particulier mais l'application peut se poursuivre par l'OPEN du curseur
puis les FETCH pour récupérer les lignes. (en revanche, un OPEN d'un
curseur déjà ouvert provoque une erreur « grave » qui aborte la
transaction)
Avec PostgreSQL, le CLOSE d'un curseur non ouvert retourne aussi un statut
d'erreur, mais la transaction en cours ne peut se poursuivre par l'OPEN du
curseur sans un rollback, mettant ainsi à mal toutes les éventuelles mises
à jour effectuées auparavant !

D'où les questions :
- Existe-t'il une solution avec PostgreSQL permettant de considérer le
CLOSE d'un curseur non ouvert comme « pas grave », c'est à dire ne mettant
pas en péril la transaction courante ?
- La norme SQL dit-elle quelque chose sur la poursuite des transactions en
cas d'erreur sur l'état d'un curseur ?

2) Détection de doublon sur INSERT

Actuellement, l'insertion d'une ligne est souvent codée de la manière
suivante :
INSERT INTO table...
IF status = uniqueness_constraint_violation
UPDATE table...
END-IF
Mais avec PostgreSQL, l'UPDATE génère une erreur car la transaction est
elle-même en erreur suite à l'INSERT qui précède.
Dans la documentation PostgreSQL, on trouve un exemple où un tel INSERT est
inclut dans un SAVEPOINT pour pouvoir faire le ROLLBACK de la
sous-transaction avant l'éventuel UPDATE.
Le principal inconvénient de ce coding réside dans le fait qu'un INSERT
nécessite alors 3 requêtes SQL (SAVEPOINT, INSERT, RELEASE SAVEPOINT) au
lieu d'une, ce qui dans notre contexte technique serait très pénalisant
(l'application et le sgbd résident sur des serveurs différents).
J'imagine que l'utilisation d'une fonction (en PL/PGSQL par exemple) qui
effectuerait l'ensemble « création ou mise à jour » permettrait d'optimiser
ce traitement.

Mais avant de creuser cette piste, j'aimerais savoir :
- S'il existe une solution avec PostgreSQL permettant de considérer la
violation d'une contrainte d'unicité comme « pas grave », c'est à dire ne
mettant pas en péril la transaction courante ?
- Si la norme SQL dit quelque chose sur la poursuite des transactions en
cas d'erreur sur violation d'une contrainte d'unicité ?

Merci par avance pour votre aide.
Philippe.

Responses

Browse pgsql-fr-generale by date

  From Date Subject
Next Message Guillaume Lelarge 2009-01-10 22:38:51 Re: Transaction en erreur sur CLOSE ou INSERT
Previous Message BPascal 2009-01-08 14:26:33 Re: tester un retour de query