PSQLException:当前事务被中止,命令被忽略,直到事务块结束

我在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 count(*)...语句,以查看ISPN_MIXED_BINARY_TABLE_configCache;
  • 出于某种原因,Postgres并不喜欢这种说法。
  • Infinispan忽略了这一点,继续使用CREATE TABLE语句。
  • Postgres吐了,因为它仍然认为它是同一个事务,Infinispan未能回滚,这个事务是从第一个SELECT count(*)...语句转过来的。

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

421782 次浏览

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

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

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

这里有一个类似的问题

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

我得到这个错误使用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, compiled by gcc (GCC) 4.7.2 20120921 (Red Hat 4.7.2-2), 64-bit".

我的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

解决方法:

你有几个选择:

  1. 最简单的解决方案:不要参与事务。将connection.setAutoCommit(false);设置为connection.setAutoCommit(true);。它可以工作,因为失败的SQL会被作为失败的SQL语句忽略。你可以随意尝试SQL语句失败,PostgreSQL不会阻止你。

  2. 保持在事务中,但是当检测到第一个SQL失败时,要么回滚/重新启动事务,要么提交/重新启动事务。然后,您可以继续在该数据库连接上失败任意数量的SQL查询。

  3. 不要捕捉和忽略SQL语句失败时抛出的异常。然后程序将在格式错误的查询上停止。

  4. 请改用Oracle,当您在事务中查询连接失败并继续使用该连接时,Oracle不会抛出异常。

为了捍卫PostgreSQL这样做的决定…Oracle 使你在中间软,让你做愚蠢的事情,忽略它。

这是PostgreSQL非常奇怪的行为,它甚至不符合PostgreSQL强迫用户显式处理所有内容的理念——因为异常被显式地捕获并忽略了。所以这个辩护也站不住脚。在这种情况下,Oracle表现得更友好,(对我来说)是正确的——它把选择留给了开发人员。

将隔离级别从可重复读更改为已提交读。

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

在你执行一个可以throw 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

在Ruby on Rails PG中,我已经创建了一个迁移,迁移了我的DB,但忘记重新启动我的开发服务器。我重启了我的服务器,它工作了。

我只是遇到了同样的错误。我能够通过在本地PostgreSQL中启用log_statementlog_min_error_statement来找出根本原因。

我引用了

出现这个错误的原因是之前有其他数据库的错误操作导致当前数据库的操作无法进行(我使用谷歌翻译将我的中文翻译成英文)

我正在使用JDBI和Postgres,遇到了同样的问题,即在违反了前一个事务语句的某些约束后,后续语句将失败(但在我等了一段时间后,比如20-30秒,问题就消失了)。

经过一些研究,我发现问题是我在我的JDBI中“手动”执行事务,即我用BEGIN;…COMMIT;事实证明,它就是罪魁祸首!

在JDBI v2中,我可以添加@Transaction注释,@SqlQuery或@SqlUpdate中的语句将作为事务执行,上面提到的问题就不会再发生了!

在postgresql JDBC驱动程序上做了一些工作,与此行为相关:
看到https://github.com/pgjdbc/pgjdbc/pull/477 < / p >

现在可以通过在连接中设置

autosave =总
(参见https://jdbc.postgresql.org/documentation/head/connect.html)来避免“当前事务被中止”综合征。由于处理语句执行前后的保存点而产生的开销非常低(详情参见上面的链接)。

我也有同样的问题,但后来意识到在数据库中有一个同名的表。删除后,我可以导入文件。

在我的情况下,我得到这个错误,因为我的文件是腐败的。而迭代文件的记录,它给我同样的错误。

也许将来它对任何人都有帮助。这是我发布这个答案的唯一原因。

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

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

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

我正在使用spring boot jpa并通过实现修复 @EnableTransactionManagement < / p >

所附文件可能会帮助你

我正在使用spring boot jpa并通过实现修复 @EnableTransactionManagement < / p >

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

试试这个COMMIT;

我在pgadmin4中运行。这可能会有所帮助。 它与前面的命令过早停止有关

对我来说,问题是没有安装驱动程序。我下载了驱动程序,并粘贴到~/Library/Tableau/ driver (mac)文件夹&它工作。

我在我的DB应用程序工具中遇到这个错误,因为有一个未提交的事务。 我试着运行一个选择查询。这就得到了这个错误。 你可以通过运行

来修复这些问题
commit;

rollback;