270 votes

PSQLException : la transaction en cours est interrompue, les commandes sont ignorées jusqu'à la fin du bloc de transaction.

Je vois la trace de pile suivante (tronquée) dans le fichier server.log de JBoss 7.1.1 Final :

Caused by: org.postgresql.util.PSQLException: 
ERROR: current transaction is aborted, commands ignored until end of 
transaction block

at org.postgresql.core.v3.QueryExecutorImpl.receiveErrorResponse(QueryExecutorImpl.java:2102)
at org.postgresql.core.v3.QueryExecutorImpl.processResults(QueryExecutorImpl.java:1835)
at org.postgresql.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.java:257)
at org.postgresql.jdbc2.AbstractJdbc2Statement.execute(AbstractJdbc2Statement.java:512)
at org.postgresql.jdbc2.AbstractJdbc2Statement.executeWithFlags(AbstractJdbc2Statement.java:374)
at org.postgresql.jdbc2.AbstractJdbc2Statement.executeUpdate(AbstractJdbc2Statement.java:302)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) [rt.jar:1.6.0_23]
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) [rt.jar:1.6.0_23]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) [rt.jar:1.6.0_23]
at java.lang.reflect.Method.invoke(Method.java:597) [rt.jar:1.6.0_23]
at org.postgresql.ds.jdbc23.AbstractJdbc23PooledConnection$StatementHandler.invoke(AbstractJdbc23PooledConnection.java:455)
at $Proxy49.executeUpdate(Unknown Source)   at org.jboss.jca.adapters.jdbc.WrappedStatement.executeUpdate(WrappedStatement.java:371)
at org.infinispan.loaders.jdbc.TableManipulation.executeUpdateSql(TableManipulation.java:154) [infinispan-cachestore-jdbc-5.1.2.FINAL.jar:5.1.2.FINAL]
... 154 more

L'inspection du fichier journal de Postgres révèle les déclarations suivantes :

STATEMENT:  SELECT count(*) FROM ISPN_MIXED_BINARY_TABLE_configCache
ERROR:  current transaction is aborted, commands ignored until end of transaction block
STATEMENT:  CREATE TABLE ISPN_MIXED_BINARY_TABLE_configCache(ID_COLUMN VARCHAR(255) NOT NULL, DATA_COLUMN BYTEA, TIMESTAMP_COLUMN BIGINT, PRIMARY KEY (ID_COLUMN))
ERROR:  relation "ispn_mixed_binary_table_configcache" does not exist at character 22

J'utilise l'Infinispan livré avec JBoss 7.1.1 Final, qui est 5.1.2.Final.

Voici donc ce que je pense qu'il se passe :

  • Infinispan tente d'exécuter le SELECT count(*)... afin de voir s'il y a des enregistrements dans le fichier ISPN_MIXED_BINARY_TABLE_configCache ;
  • Postgres, pour une raison quelconque, n'aime pas cette déclaration.
  • Infinispan l'ignore et continue avec la méthode CREATE TABLE déclaration.
  • Postgres se dégonfle parce qu'il pense toujours qu'il s'agit de la même transaction, qu'Infinispan n'a pas réussi à annuler, et que cette transaction s'est fait avoir dès le départ. SELECT count(*)... déclaration.

Que signifie cette erreur et comment la contourner ?

0 votes

Si vous êtes venu ici comme moi, en cherchant ce qui précède. PSQLException: current transaction is aborted... ( 25P02 ) et peut-être aussi JPA ou Hibernate . Finalement, c'est grâce à notre (belle !) Logback usage alimenté par un toString() -L'objet DAO surchargé qui a causé l'erreur et a été gentiment avalé (mais accidentellement inaperçu par moi) : log.info( "bla bla: {}", obj ) produit bla bla: [FAILED toString()] . en le changeant en log.info( "bla bla: {}", String.valueOf( obj ) la rendait nulle, mais ne l'avalait pas et laissait ainsi la transaction ouverte échouer sur une requête sans rapport.

0 votes

J'ai eu le même type d'erreur. J'ai dû libérer la connexion avant le sql. Mon code était connection.commit()

0 votes

J'ai répondu ici stackoverflow.com/a/65172183/3323007 et ça marche !

313voto

Eric Leschinski Points 14289

J'ai obtenu cette erreur en utilisant Java et PostgreSQL en faisant une insertion sur une table. Je vais illustrer comment vous pouvez reproduire cette erreur :

org.postgresql.util.PSQLException: ERROR: 
current transaction is aborted, commands ignored until end of transaction block

Résumé :

La raison pour laquelle vous obtenez cette erreur est que vous avez entré une transaction et que l'une de vos requêtes SQL a échoué, et que vous avez absorbé cet échec et l'avez ignoré. Mais cela n'a pas suffi, vous avez ensuite utilisé cette même connexion, en utilisant la MÊME TRANSACTION pour exécuter une autre requête. L'exception est levée sur la seconde requête, correctement formée, parce que vous utilisez une transaction cassée pour effectuer un travail supplémentaire. PostgreSQL vous empêche par défaut de faire cela.

Je l'utilise : PostgreSQL 9.1.6 on x86_64-redhat-linux-gnu, compiled by gcc (GCC) 4.7.2 20120921 (Red Hat 4.7.2-2), 64-bit".

Mon pilote PostgreSQL est : postgresql-9.2-1000.jdbc4.jar

Utilisation de la version Java : Java 1.7

Voici l'instruction de création de table pour illustrer l'exception :

CREATE TABLE moobar
(
    myval   INT
);

Le programme Java provoque l'erreur :

public void postgresql_insert()
{
    try  
    {
        connection.setAutoCommit(false);  //start of transaction.

        Statement statement = connection.createStatement();

        System.out.println("start doing statement.execute");

        statement.execute(
                "insert into moobar values(" +
                "'this SQL statement fails, and it " +
                "is gobbled up by the catch, okfine'); ");

        //The above line throws an exception because we try to cram
        //A string into an Int.  I Expect this, what happens is we gobble 
        //the Exception and ignore it like nothing is wrong.
        //But remember, we are in a TRANSACTION!  so keep reading.

        System.out.println("statement.execute done");

        statement.close();

    }
    catch (SQLException sqle)
    {
        System.out.println("keep on truckin, keep using " +
                "the last connection because what could go wrong?");
    }

    try{
        Statement statement = connection.createStatement();

        statement.executeQuery("select * from moobar");

        //This SQL is correctly formed, yet it throws the 
        //'transaction is aborted' SQL Exception, why?  Because:
        //A.  you were in a transaction.
        //B.  You ran a SQL statement that failed.
        //C.  You didn't do a rollback or commit on the affected connection.

    }
    catch (SQLException sqle)
    {
        sqle.printStackTrace();
    }   

}

Le code ci-dessus produit ce résultat pour moi :

start doing statement.execute

keep on truckin, keep using the last connection because what could go wrong?

org.postgresql.util.PSQLException: 
  ERROR: current transaction is aborted, commands ignored until 
  end of transaction block

Solutions de contournement :

Vous avez quelques options :

  1. La solution la plus simple : Ne soyez pas dans une transaction. Mettez le connection.setAutoCommit(false); à connection.setAutoCommit(true); . Cela fonctionne parce qu'alors le SQL échoué est simplement ignoré comme une instruction SQL échouée. Vous pouvez faire échouer des instructions SQL autant que vous voulez et PostgreSQL ne vous en empêchera pas.

  2. Restez dans une transaction, mais lorsque vous détectez que la première requête SQL a échoué, faites un retour en arrière/redémarrez ou engagez/redémarrez la transaction. Vous pouvez ensuite continuer à faire échouer autant de requêtes SQL que vous le souhaitez sur cette connexion à la base de données.

  3. Ne pas attraper et ignorer l'exception qui est levée lorsqu'une instruction SQL échoue. Le programme s'arrêtera alors sur la requête malformée.

  4. À la place, Oracle ne lève pas d'exception lorsque vous échouez une requête sur une connexion dans une transaction et que vous continuez à utiliser cette connexion.

Pour défendre la décision de PostgreSQL de faire les choses de cette façon... Oracle était te rendant mou au milieu, te laissant faire des choses stupides et les ignorant.

22 votes

Lol @ Option 4... J'ai fait pas mal de développement avec Oracle, et j'ai récemment commencé à utiliser Postgres... c'est vraiment ennuyeux que Postgres fasse cela, et maintenant nous devons vraiment réécrire une grande partie de notre programme que nous portons d'Oracle à Postgres. Pourquoi n'y a-t-il pas une option comme la première pour qu'il se comporte comme Oracle mais sans l'auto-commit ?

3 votes

J'ai découvert après quelques essais que Option 2 est ce qui se rapproche le plus du comportement d'Oracle. Si vous devez émettre plusieurs mises à jour, et qu'un échec ne doit pas arrêter les mises à jour suivantes, appelez simplement rollback() sur le Connection lorsqu'un SQLException est pris. [ Quoi qu'il en soit Je me suis rendu compte que cela correspond à la philosophie de PostgreSQL, qui oblige l'utilisateur à tout expliciter, alors qu'Oracle a pour philosophie de s'occuper implicitement de beaucoup de choses].

0 votes

Existe-t-il un moyen de vérifier l'objet Connexion (en Java) pour savoir si une transaction a échoué ?

45voto

vyegorov Points 6487

Vérifiez la sortie avant la déclaration qui a provoqué current transaction is aborted . Cela signifie généralement que la base de données a déclenché une exception que votre code a ignorée et que vous attendez maintenant que les prochaines requêtes renvoient des données.

Vous avez donc maintenant un décalage d'état entre votre application, qui considère que tout va bien, et la base de données, qui vous oblige à revenir en arrière et à recommencer votre transaction depuis le début.

Vous devez attraper toutes les exceptions et annuler les transactions dans de tels cas.

Voici un problème similaire.

0 votes

C'est très bien, sauf que dans ce cas, c'est Infinispan, une bibliothèque tierce, qui parle à Postgres, et non mon code.

0 votes

Eh bien, la situation est toujours la même - la transaction doit être annulée. Vérifiez peut-être s'il existe une version plus récente de la bibliothèque que vous utilisez ou soulevez le problème dans leur bug tracker. Si vous trouvez le problème exact SQL qui a causé le problème, vous aurez du champ pour éliminer le problème en utilisant l'extensibilité de PostgreSQL.

0 votes

Il semble que vous ayez confirmé mes soupçons - je vais maintenant regarder les sources d'Infinispan 5.1.2.

3voto

Dan Berindei Points 2326

Le problème a été corrigé dans Infinispan 5.1.5.CR1 : ISPN-2023

1voto

al0 Points 17

C'est un comportement très étrange de PostgreSQL, ce n'est même pas "en ligne avec la philosophie de PostgreSQL de forcer l'utilisateur à rendre tout explicite" - puisque l'exception a été capturée et ignorée explicitement. Donc même cette défense ne tient pas. Oracle dans ce cas se comporte de manière beaucoup plus conviviale et (en ce qui me concerne) correcte - il laisse le choix au développeur.

-1voto

user2667525 Points 41

J'ai ce ERROR : PSQLException : la transaction en cours est interrompue, les commandes sont ignorées jusqu'à la fin du bloc de transaction.

J'ai essayé d'importer une table à partir de la ligne de commande "shp2pgsql" mais cela échoue car la relation ou la table existe déjà.

alors j'ai supprimé ma table avant l'importation et cela fonctionne.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X