我在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计数(*)…声明。
这个错误意味着什么,你知道如何解决它吗?
我得到这个错误使用Java和PostgreSQL做一个表上的插入。我将说明如何重现这个错误:
org.postgresql.util.PSQLException: ERROR:
current transaction is aborted, commands ignored until end of transaction block
简介:
您得到这个错误的原因是因为您输入了一个事务,其中一个SQL查询失败了,您接受了这个失败并忽略了它。但这还不够,然后使用相同的连接,使用相同的TRANSACTION运行另一个查询。在第二个格式正确的查询上抛出异常,因为您正在使用一个损坏的事务来执行额外的工作。PostgreSQL默认阻止你这样做。
我使用的是:PostgreSQL 9.1.6 on x86_64-redhat-linux-gnu,由gcc (gcc) 4.7.2 20120921 (Red Hat 4.7.2-2)编译,64位”。
我的PostgreSQL驱动是:PostgreSQL -9.2-1000.jdbc4.jar
使用Java版本:Java 1.7
下面是表创建语句来说明异常:
CREATE TABLE moobar
(
myval INT
);
Java程序导致错误:
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();
}
}
上面的代码为我产生了以下输出:
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
解决方法:
你有几个选择:
Simplest solution: Don't be in a transaction. Set the connection.setAutoCommit(false); to connection.setAutoCommit(true);. It works because then the failed SQL is just ignored as a failed SQL statement. You are welcome to fail SQL statements all you want and PostgreSQL won't stop you.
Stay being in a transaction, but when you detect that the first SQL has failed, either rollback/re-start or commit/restart the transaction. Then you can continue failing as many SQL queries on that database connection as you want.
Don't catch and ignore the Exception that is thrown when a SQL statement fails. Then the program will stop on the malformed query.
Get Oracle instead, Oracle doesn't throw an exception when you fail a query on a connection within a transaction and continue using that connection.
为了捍卫PostgreSQL这样做的决定…神谕让你在中间变得软弱,让你做一些愚蠢的事情,而忽略它。