Re: Transaction en erreur sur CLOSE ou INSERT

From: Guillaume Lelarge <guillaume(at)lelarge(dot)info>
To: philippe(dot)beaudoin(at)bull(dot)net
Cc: pgsql-fr-generale(at)postgresql(dot)org
Subject: Re: Transaction en erreur sur CLOSE ou INSERT
Date: 2009-01-10 22:38:51
Message-ID: 4969237B.1050301@lelarge.info
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-fr-generale

philippe(dot)beaudoin(at)bull(dot)net a écrit :
> Bonjour à tous, et que cette nouvelle année vous soit douce...
>

Merci. Bonne année à vous aussi.

> 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.
> [...]
> 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 ?

Non. En règle générale, toute erreur pendant une transaction annule
cette transaction. Le mieux est certainement de vérifier son existence
dans la table pg_cursors avec par exemple un :

SELECT 1 FROM pg_cursors WHERE name='le nom du curseur';

L'avantage est d'éviter l'annulation de la transaction. L'inconvénient
est que ce n'est pas du tout portable. De plus, il s'agit d'une table
système, qui est donc susceptible d'évoluer entre les versions.
Maintenant, que cela évolue sur le nom du curseur, j'ai un gros doute.

Sinon, il est toujours possible d'utiliser un SAVEPOINT :

* SAVEPOINT
* tentative de fermeture du curseur
* en cas d'erreur, ROLLBACK au SAVEPOINT précédent

> - La norme SQL dit-elle quelque chose sur la poursuite des transactions en
> cas d'erreur sur l'état d'un curseur ?

Je ne connais pas assez les normes SQL pour répondre à cette question.
Et j'avoue ne pas avoir envie, un samedi soir, de me lancer dans la
lecture des quatres normes disponibles :)

> 2) Détection de doublon sur INSERT
>
> [...]
> 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 ?

Non. Comme dit ci-dessus, toute erreur annule une transaction. Je dirais
même que c'est pire dans ce cas, les contraintes d'unicité étant la base
d'un SGBD digne de ce nom. Bref, dans ce cas précis, il me semble que la
meilleure solution est d'inverser votre code. Au lieu de :

INSERT
si erreur
UPDATE

faire :

UPDATE
si aucune ligne mise à jour
INSERT

Attention, ça ne se prête pas à tous les cas. Pour ceux-là, il reste
encore le SAVEPOINT.

> - Si la norme SQL dit quelque chose sur la poursuite des transactions en
> cas d'erreur sur violation d'une contrainte d'unicité ?
>

Même remarque que tout à l'heure :)

--
Guillaume.
http://www.postgresqlfr.org
http://dalibo.com

In response to

Browse pgsql-fr-generale by date

  From Date Subject
Next Message William Dode 2009-01-11 09:33:49 Re: Transaction en erreur sur CLOSE ou INSERT
Previous Message philippe.beaudoin 2009-01-10 09:41:57 Transaction en erreur sur CLOSE ou INSERT