2008-10-12 18 views
1

J'essaye de déboguer une application (sous PostgreSQL) et j'ai rencontré l'erreur suivante: "la transaction courante est annulée, les commandes ignorées". Autant que je puisse comprendre une «transaction» est juste une notion liée à la connexion de base de données sous-jacente.Transactions, quand il faut les supprimer

Si la connexion a une validation automatique "false", vous pouvez exécuter des requêtes via la même instruction tant qu'elle n'échoue pas. Dans ce cas, vous devriez revenir en arrière.

Si la validation automatique est "true", cela n'a pas d'importance tant que toutes vos requêtes sont considérées comme atomiques.

en utilisant l'auto commit faux, j'obtiens l'erreur ci-dessus par PostgreSQL, même si simple

select * from foo 

échoue, ce qui me fait demander, en vertu de laquelle SQLException (s) est une « transaction » considérée comme non valide et devrait être rolled soutenu ou non utilisé pour une autre requête?

using MacOS 10.5, Java 1.5.0_16, PostgreSQL 8.3 with JDBC driver 8.1-407.jdbc3

Répondre

3

Cette erreur signifie que l'une des requêtes envoyées dans une transaction a échoué, de sorte que le reste des requêtes sont ignorées jusqu'à la fin de la transaction en cours (qui sera automatiquement un rollback). Pour PostgreSQL, la transaction a échoué et elle sera annulée dans tous les cas après l'erreur, à une exception près. Vous devez prendre les mesures appropriées, l'une des

  1. de rejeter l'instruction et recommencer à zéro.
  2. utilisez SAVEPOINT s dans la transaction pour pouvoir revenir à ce moment et essayer un autre chemin. (Ceci est l'exception)

Activer query logging pour voir quelle requête est en échec et pourquoi. Dans tous les cas, la réponse exacte à votre question est que n'importe quelle SQLException devrait signifier une annulation quand la commande de fin de transaction est envoyée, c'est-à-dire quand un COMMIT ou ROLLBACK (ou END) est émis. Voici comment cela fonctionne, si vous utilisez des points de sauvegarde, vous serez toujours lié par les mêmes règles, vous pourrez simplement revenir à l'endroit où vous avez sauvegardé et essayer quelque chose d'autre.

+0

Merci pour la clarification. J'ai fait quelques tests et j'ai découvert que lorsque la validation automatique est définie sur false * sous PostgreSQL * lorsqu'une exception se produit, vous * roll * rollback pour exécuter l'instruction suivante (vous pouvez réutiliser celle existante autant que je peux). Ce n'est pas * le cas de mySQL par exemple. – qnoid

+0

Oui, voici comment cela fonctionne, je ne comprends pas encore ce qui est encore flou dans la réponse. Que je n'ai pas mentionné que ce n'est pas comme ça dans d'autres SGBD? Pourquoi cela serait-il pertinent? :)BTW, ce que vous devez faire est de terminer la transaction en cours ou d'obtenir un état enregistré non-erroné en elle. –

1

Il semble que ce soit un comportement caractéristique de PostgreSQL qui n'est pas partagé par la plupart des autres SGBD. En général (en dehors de PostgreSQL), vous pouvez faire échouer une opération à cause d'une erreur et ensuite, dans la même transaction, essayer des actions alternatives qui réussiront, en compensant l'erreur. Un exemple: considérez une opération de fusion (insertion/mise à jour). Si vous essayez d'INSÉRER le nouvel enregistrement mais constatez qu'il existe déjà, vous pouvez basculer vers une opération UPDATE qui modifie l'enregistrement existant à la place. Cela fonctionne très bien dans tous les principaux SGBD. Je ne suis pas certain que cela ne fonctionne pas dans PostgreSQL, mais les descriptions que j'ai vues ailleurs, ainsi que dans cette question, suggèrent que lorsque la tentative INSERT signifie que toute activité supplémentaire dans la transaction est vouée à l'échec aussi. Ce qui est au mieux draconien et au pire «inutilisable».

+0

merci! c'est pourquoi j'ai demandé "Alors pourquoi l'erreur mentionnée ci-dessus par PostgreSQL alors?" Donc, étant donné que c'est lié à PostgreSQL, cela signifie-t-il que vous êtes vraiment obligé d'écrire du code spécifique au vendeur pour gérer SQLException (s), ou est-ce une bonne habitude de rejeter une déclaration et de recommencer? – qnoid

+0

"Le point essentiel d'une transaction est qu'elle regroupe plusieurs étapes en une seule opération" tout ou rien "." –

+0

Cela signifie-t-il que vous devriez * toujours * revenir en arrière lorsqu'une exception se produit, quelle que soit l'instruction? – qnoid