2012-05-01 18 views
99

estoy viendo la StackTrace siguiente (truncado) en el archivo server.log de JBoss 7.1.1 final:PSQLException: transacción actual se aborta, comandos ignorados hasta el final del bloque de transacción

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 

Inspección del registro de Postgres archivo revela las siguientes declaraciones:

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 

estoy usando el Infinispan envía con JBoss 7.1.1 final, que es 5.1.2.Final.

Así que esto es lo que creo que está pasando:

  • Infinispan intenta ejecutar la instrucción SELECT count(*)... con el fin de ver si hay algún registros en la ISPN_MIXED_BINARY_TABLE_configCache;
  • Postgres, por alguna razón, no le gusta esta afirmación.
  • Infinispan ignora esto y sigue adelante con la instrucción CREATE TABLE.
  • Postgres barfs porque todavía cree que es la misma transacción, que Infinispan no ha podido revertir, y esta transacción se deriva de la primera declaración SELECT count(*)....

¿Qué significa este error y alguna idea de cómo solucionarlo?

+0

Simplemente si vino aquí como yo buscando la 'PSQLException 'anterior: se cancela la transacción actual ...' ('25P02') y tal vez también' JPA' o 'Hibernate'. Finalmente, fue debido a nuestro (agradable) ** uso de Logback ** alimentado con un objeto DAO 'toString() 'sobrecargado que causó el error y fue muy bien tragado (pero desapercibido accidentalmente por mí):' log.info (" bla bla: {} ", obj)' producido ** 'bla bla: [FAILED toString()]' **. cambiándolo a 'log.info (" bla bla: {} ", String.valueOf (obj)' lo convirtió en nulo seguro, pero no lo tragó y así dejó la transacción abierta en una consulta no relacionada. –

Respuesta

18

Compruebe la salida antes de la declaración que provocó current transaction is aborted. Esto normalmente significa que la base de datos lanzó una excepción que su código había ignorado y ahora espera que las próximas consultas devuelvan algunos datos.

Así que ahora tiene una discrepancia de estado entre su aplicación, que considera que todo está bien, y la base de datos, que requiere que restituya y reinicie su transacción desde el principio.

Debe detectar todas las excepciones y transacciones de retrotracción en tales casos.

Here's a similar issue.

+0

Eso es genial, excepto en este caso sería Infinispan, una biblioteca de terceros, hablando con Postgres y no con mi código. – Jimidy

+0

Bueno, la situación sigue siendo la misma: la transacción tiene que revertirse. Tal vez compruebe si hay una versión más nueva de la biblioteca que está utilizando o plantee el problema en su rastreador de errores. Si encuentra el 'SQL 'exacto que causó el problema, tendrá algún campo para eliminar el problema usando la extensibilidad de PostgreSQL. – vyegorov

+0

Parece que ha confirmado mis sospechas: voy a ver la fuente de Infinispan 5.1.2 ahora. – Jimidy

2

El problema se ha solucionado en Infinispan 5.1.5.CR1: ISPN-2023

130

Tengo este error utilizando Java y PostgreSQL hacer una inserción en una tabla. Voy a ilustrar cómo se puede reproducir este error:

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

Resumen:

La razón por la que este error se debe a que ha entrado en una transacción y uno de sus falló consultas SQL, y engullido hasta ese fracaso y lo ignoró. Pero eso no fue suficiente, ENTONCES usaste esa misma conexión, usando la MISMA TRANSACCIÓN para ejecutar otra consulta. La excepción se aplica a la segunda consulta, formada correctamente, porque está utilizando una transacción interrumpida para realizar un trabajo adicional. Postgresql por defecto te impide hacer esto.

que estoy usando: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".

Mi conductor PostgreSQL es:postgresql-9.2-1000.jdbc4.jar

Al usar la versión de Java:Java 1.7

Aquí está la tabla de sentencia de creación para ilustrar la Excepción :

CREATE TABLE moobar 
(
    myval INT 
); 

programa Java provoca el error:

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(); 
    } 

} 

El código anterior produce esta salida para mí:

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 

Soluciones:

usted tiene unos pocos opciones:

  1. Solución más simple: No te metas en una transacción. Establezca connection.setAutoCommit(false); en connection.setAutoCommit(true);. Funciona porque el SQL fallido simplemente se ignora como una declaración sql fallida. Le invitamos a fallar sentencias sql todo lo que desee y postgresql no lo detendrá.

  2. Permanezca en una transacción, pero cuando detecte que el primer sql ha fallado, revertir/reiniciar o confirmar/reiniciar la transacción. Entonces puede continuar fallando tantas consultas sql en esa conexión de base de datos como desee.

  3. No capte e ignore la excepción que se produce cuando falla una instrucción sql. Entonces el programa se detendrá en la consulta mal formada.

  4. Obtenga Oracle en su lugar, Oracle no lanza una excepción cuando falla una consulta en una conexión dentro de una transacción y continúa usando esa conexión.

En defensa de la decisión de PostgreSQL para hacer las cosas de esta manera ... Oracle fue hacer que se blando en el medio que le permite hacer cosas tontas y con vistas a él.

+5

Lol @ Opción 4 ... He hecho bastante desarrollo en Oracle, y recientemente comencé a usar Postgres ... es realmente molesto que Postgres haga esto, y ahora tenemos que estar realmente reescribiendo una gran parte de nuestro programa que estamos migrando de Oracle a Postgres. ¿Por qué no hay una opción como la primera para que se comporte como Oracle, pero ** sin la confirmación automática **? – ADTC

+2

Después de algunas pruebas se descubrió que ** Opción 2 ** es lo más cercano que se puede llegar al comportamiento de Oracle. Si necesita emitir varias actualizaciones, y una falla no debe detener las actualizaciones posteriores, simplemente llame a 'rollback()' en 'Connection' cuando se capture' SQLException'. [_Anyway_ Me di cuenta de que esto está en línea con la filosofía de PostgreSQL de obligar al usuario a hacer todo explícito, mientras que Oracle tiene la filosofía de ocuparse implícitamente de muchas cosas.] – ADTC

+0

¿Hay alguna manera de verificar el objeto Connection (en Java) para ver si una transacción ha fallado. –

0

Este es un comportamiento muy extraño de PostgreSQL, incluso no está "en línea con la filosofía de PostgreSQL de obligar al usuario a hacer que todo sea explícito", ya que la excepción fue capturada e ignorada explícitamente. Entonces incluso esta defensa no se sostiene. En este caso, Oracle se comporta de manera mucho más amigable y (en mi caso) correctamente, deja una elección al desarrollador.

-1

Cambie el nivel de aislamiento de lectura repetible a lectura confirmada.

7

Creo que la mejor solución es usar java.sql.Savepoint.

Antes de ejecutar la consulta que puede arrojar SQLException use el método Connection.setSavepoint() y, si se produce una excepción, solo revertirá a este punto de rescate no revertirá todas las transacciones.

código Ejemplo:

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) {} 

    } 
} 
+0

Accidentalmente downvoted de alguna manera, solo se acaba de dar cuenta. No fue intencional, no puedo deshacer a menos que se edite la respuesta. – cerberos

0

Esto puede suceder si usted está fuera de espacio en disco en el volumen.

+0

Me doy cuenta de que esta no es la causa más común, pero este fue el caso en un servidor que me pidieron que resolviera. Así que creo que esto debería figurar como una posible causa. – gregb

2

Es necesario retroceder. El controlador JDBC Postgres es bastante malo. Pero si usted quiere mantener su transacción, y acaba de deshacer ese error, puede utilizar puntos de retorno:

try { 
_stmt = connection.createStatement(); 
_savePoint = connection.setSavepoint("sp01"); 
_result = _stmt.executeUpdate(sentence) > 0; 
} catch (Exception e){ 
if (_savePoint!=null){ 
connection.rollback(_savePoint); 
} 
} 

Leer más aquí:

http://www.postgresql.org/docs/8.1/static/sql-savepoint.html

4

en Ruby on Rails PG, que había creado una migración, migré mi base de datos, pero olvidé reiniciar mi servidor de desarrollo. Reinicié mi servidor y funcionó.

1

La razón de este error es que hay otra base de datos antes de la operación equivocada condujo a la operación de la base de datos actual no puede llevarse a cabo (i utilizar traducción de Google para traducir mi chino a Inglés)

0

Estoy usando JDBI con Postgres, y encontré el mismo problema, es decir, después de una violación de alguna restricción de una declaración de una transacción anterior, las siguientes declaraciones fallarían (pero después de esperar un tiempo, digamos 20-30 segundos, el problema desaparece).

Después de algunas investigaciones, encontré que el problema era que estaba haciendo una transacción "manualmente" en mi JDBI, es decir, rodeé mis declaraciones con BEGIN; ... COMMIT; y resulta ser el culpable!

En JDBI v2, puedo simplemente agregar la anotación @Transaction, y las declaraciones dentro de @SqlQuery o @SqlUpdate se ejecutarán como una transacción, y el problema mencionado anteriormente ya no ocurre.

0

Ha habido algún trabajo realizado en el controlador PostgreSQL JDBC, en relación con este comportamiento:
ver https://github.com/pgjdbc/pgjdbc/pull/477

Ahora es posible, mediante el establecimiento de

autosave=always
en la conexión (ver https://jdbc.postgresql.org/documentation/head/connect.html) para evitar la 'transacción actual es síndroma abortado.
Overhead debido a la gestión de un punto de rescate en torno a la ejecución de la declaración se mantiene muy bajo (ver enlace arriba para más detalles).

0

Tuve el mismo problema pero luego me di cuenta de que hay una tabla con el mismo nombre en la base de datos. Después de eliminar que pude importar el archivo.

Cuestiones relacionadas