我在JBoss 7.1.1 Final的server.log文件中看到了以下(截断的)stacktrace:

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

检查Postgres日志文件会发现以下语句:

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

我使用的是JBoss 7.1.1 Final附带的Infinispan,它是5.1.2.Final。

这就是我认为正在发生的事情:

Infinispan试图运行SELECT计数(*)…语句,以查看ISPN_MIXED_BINARY_TABLE_configCache中是否有记录; 出于某种原因,Postgres并不喜欢这种说法。 Infinispan忽略了这一点,继续使用CREATE TABLE语句。 Postgres吐了,因为它仍然认为这是同一个事务,Infinispan未能回滚,这个事务是从第一个SELECT计数(*)…声明。

这个错误意味着什么,你知道如何解决它吗?


当前回答

我正在使用spring boot jpa,并通过实现来修复 @EnableTransactionManagement

附上的文件可能会帮助你。

其他回答

该问题已在Infinispan 5.1.5中修复。CR1: ispn - 2023

我使用带有@Transactional注释的spring,我捕获了异常,对于某些异常,我将重试3次。

对于posgresql,当get异常时,不能再使用同一个Connection进行提交。必须先进行回退。

对于我的例子,我使用DatasourceUtils来获取当前连接并手动调用connection.rollback()。并且调用方法recruit来重试。

在导致当前事务中止的语句之前检查输出。这通常意味着数据库抛出了一个您的代码忽略的异常,现在期望下一个查询返回一些数据。

因此,现在您的应用程序(认为一切正常)和数据库(需要从头回滚并重新启动事务)之间的状态不匹配。

在这种情况下,您应该捕获所有异常并回滚事务。

这里有一个类似的问题。

我认为最好的解决方案是使用java.sql.Savepoint。

在执行可能引发SQLException的查询之前,使用Connection.setSavepoint()方法,如果抛出异常,则只回滚到该保存点,而不是整个事务。

示例代码:

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

   }
}

需要回退。JDBC Postgres驱动程序非常糟糕。但如果你想保留你的事务,只是回滚那个错误,你可以使用savepoints:

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

点击此处阅读更多信息:

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