Je vois le stacktrace suivant (tronqué) 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 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.
Donc, voici ce que je pense qui se passe:
SELECT count(*)...
afin de voir s'il existe des enregistrements dans le ISPN_MIXED_BINARY_TABLE_configCache
;CREATE TABLE
.SELECT count(*)...
.Qu'est-ce que cette erreur signifie et une idée sur la façon de la contourner?
J'ai eu cette erreur en utilisant Java et postgresql faire 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é:
Si vous obtenez cette erreur, c'est parce que vous avez entré une transaction et qu'une de vos requêtes SQL a échoué, que vous avez englouti cet échec et que vous l'avez ignoré. Mais cela ne suffisait pas, ALORS vous avez utilisé la même connexion, en utilisant SAME TRANSACTION pour exécuter une autre requête. L'exception est levée sur la deuxième requête correctement formée parce que vous utilisez une transaction cassée pour effectuer un travail supplémentaire. Postgresql par défaut vous empêche de le faire.
J'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 illustrant 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 génère cette sortie 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
Contournements:
Vous avez quelques options:
Solution la plus simple: ne soyez pas dans une transaction. Définissez connection.setAutoCommit(false);
sur connection.setAutoCommit(true);
. Cela fonctionne parce qu'alors le SQL ayant échoué est simplement ignoré en tant qu'instruction SQL ayant échoué. Vous êtes le bienvenu pour faire échouer les déclarations SQL tout ce que vous voulez et postgresql ne vous arrêtera pas.
Restez dans une transaction, mais lorsque vous détectez que le premier SQL a échoué, annulez/redémarrez ou validez/redémarrez la transaction. Ensuite, vous pouvez continuer à échouer autant de requêtes SQL que vous le souhaitez sur cette connexion à la base de données.
Ne pas attraper et ignorer l'exception qui est levée quand une instruction SQL échoue. Ensuite, le programme s'arrêtera sur la requête malformée.
Si vous obtenez Oracle, Oracle ne lève pas d'exception lorsque vous échouez à une requête sur une connexion dans une transaction et continuez à utiliser cette connexion.
Pour défendre la décision de postgresql de faire les choses de cette façon ... Oracle vous rendait doux au milieu, vous permettant de faire des choses idiotes et de les ignorer.
Vérifiez la sortie avant l'instruction à l'origine de current transaction is aborted
. Cela signifie généralement que la base de données a généré une exception que votre code avait ignorée et attend maintenant que les prochaines requêtes renvoient des données.
Vous avez donc maintenant une incompatibilité d'état entre votre application, qui considère que tout va bien, et la base de données, qui vous oblige à annuler et à redémarrer votre transaction depuis le début.
Dans ce cas, vous devez intercepter toutes les exceptions et les transactions d'annulation.
Je pense que la meilleure solution consiste à utiliser Java.sql.Savepoint.
Avant d'exécuter une requête qui peut générer une exception SQLException, utilisez la méthode Connection.setSavepoint () et, si une exception survient, vous restaurez uniquement la restauration de ce point de sauvegarde, pas la restauration complète.
Exemple de code:
Connection conn = null;
Savepoint savepoint = null;
try {
conn = getConnection();
savepoint = conn.setSavepoint();
//execute some query
} catch(SQLException e) {
if(conn != null && savepoint != null) {
conn.rollback(savepoint);
}
} finally {
if(conn != null) {
try {
conn.close();
} catch(SQLException e) {}
}
}
Dans Ruby on Rails PG, j'avais créé une migration, migré ma base de données, mais j'avais oublié de redémarrer mon serveur de développement. J'ai redémarré mon serveur et cela a fonctionné.
La raison de cette erreur est qu’il existe d’autres bases de données avant que la mauvaise opération qui a conduit à l’opération de base de données actuelle ne puisse pas être effectuée j’utilise la traduction google pour traduire mon chinois en anglais
Vous devez revenir en arrière. Le pilote JDBC Postgres est assez mauvais. Mais si vous souhaitez conserver votre transaction et annuler simplement cette erreur, vous pouvez utiliser des points de sauvegarde:
try {
_stmt = connection.createStatement();
_savePoint = connection.setSavepoint("sp01");
_result = _stmt.executeUpdate(sentence) > 0;
} catch (Exception e){
if (_savePoint!=null){
connection.rollback(_savePoint);
}
}
Lire la suite ici:
http://www.postgresql.org/docs/8.1/static/sql-savepoint.html
Le problème a été corrigé dans Infinispan 5.1.5.CR1: ISPN-2023
Des travaux ont été effectués sur le pilote JDBC postgresql, liés à ce problème:
voir https://github.com/pgjdbc/pgjdbc/pull/477
Il est maintenant possible, en mettant
autosave = toujoursdans la connexion (voir https://jdbc.postgresql.org/documentation/head/connect.html ) pour éviter le syndroma 'La transaction en cours est annulée'.
J'avais le même problème mais j'ai alors réalisé qu'il y avait une table du même nom dans la base de données. Après avoir supprimé cela, j'ai pu importer le fichier.
C'est un comportement très étrange de PostgreSQL, il n'est même pas "en ligne avec la philosophie de PostgreSQL consistant à obliger l'utilisateur à tout rendre explicite" - car l'exception a été interceptée et ignorée explicitement. Donc, même cette défense ne tient pas. Oracle dans ce cas se comporte beaucoup plus convivial et (comme pour moi) correctement - cela laisse un choix au développeur.
Je viens de rencontrer la même erreur. J'ai pu comprendre la cause en activant les instructions log_statement et log_min_error_error dans ma version locale de PostgreSQL.
J'ai référé this
Définissez conn.setAutoCommit (false) sur conn.setAutoCommit (true)
Commettez les transactions avant d’en initier une nouvelle.
J'utilise JDBI avec Postgres et rencontre le même problème, c'est-à-dire qu'après violation d'une contrainte d'une déclaration d'une transaction précédente, les déclarations suivantes échouent (mais après avoir attendu un certain temps, par exemple 20-30 secondes, le problème disparaît ).
Après quelques recherches, j’ai trouvé que le problème était que je faisais une transaction "manuellement" dans mon JDBI, c’est-à-dire que je cernais mes déclarations avec BEGIN; ... COMMIT; et il s'avère que c'est le coupable!
Dans JDBI v2, je peux simplement ajouter une annotation @Transaction et les instructions contenues dans @SqlQuery ou @SqlUpdate seront exécutées en tant que transaction et le problème mentionné ci-dessus ne se produit plus!
Cela peut arriver si vous manquez d'espace disque sur le volume.