繁体   English   中英

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

[英]PSQLException: current transaction is aborted, commands ignored until end of transaction block

我在 JBoss 7.1.1 Final 的 server.log 文件中看到以下(截断的)堆栈跟踪:

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 barfs,因为它仍然认为它是同一个事务,Infinispan 未能回滚,并且这个事务是从第一个SELECT count(*)...语句开始的。

这个错误是什么意思,知道如何解决它吗?

我使用 Java 和 PostgreSQL 在表上插入时遇到此错误。 我将说明如何重现此错误:

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

概括:

您收到此错误的原因是因为您输入了一个事务并且其中一个 SQL 查询失败,而您吞噬了该失败并忽略了它。 但这还不够,然后您使用相同的连接,使用 SAME 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

这是用于说明异常的 table create 语句:

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的决定,这样做事的防御......甲骨文让你在柔和你做愚蠢的东西中间出租,可俯瞰它。

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

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

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

这是一个类似的问题。

我认为最好的解决方案是使用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) {}

   }
}

已经在 postgresql JDBC 驱动程序上完成了一些与此行为相关的工作:
https://github.com/pgjdbc/pgjdbc/pull/477

现在可以通过设置

autosave=always
在连接中(参见https://jdbc.postgresql.org/documentation/head/connect.html )避免“当前事务中止”综合症。
由于处理语句执行周围的保存点而导致的开销非常低(有关详细信息,请参见上面的链接)。

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

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

试试这个COMMIT;

我在 pgadmin4 中运行它。 它可能会有所帮助。 它与上一个命令过早停止有关

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

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

该问题已在 Infinispan 5.1.5.CR1: ISPN-2023 中得到修复

我遇到了同样的问题,但后来意识到数据库中有一个同名的表。 删除后,我能够导入文件。

如果卷上的磁盘空间不足,就会发生这种情况。

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

这是 PostgreSQL 非常奇怪的行为,它甚至不“符合 PostgreSQL 强制用户将所有内容都明确化的哲学”——因为异常被明确地捕获并忽略。 所以即使是这种防御也不成立。 在这种情况下,Oracle 的行为更加用户友好并且(就我而言)正确 - 它为开发人员留下了选择。

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

我提到了这个

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

经过一些研究,我发现问题是我在 JDBI 中“手动”进行事务处理,即我用 BEGIN;...COMMIT; 包围了我的语句。 事实证明它是罪魁祸首!

在JDBI v2中,我只需添加@Transaction注解,@SqlQuery或@SqlUpdate中的语句就会作为一个事务执行,不再出现上述问题!

就我而言,我收到此错误是因为我的文件已损坏。 在迭代文件记录时,它给了我同样的错误。

可能在未来它会帮助任何人。 这是发布此答案的唯一原因。

我将 spring 与@Transactional注释一起使用,并捕获异常,对于某些异常,我将重试 3 次。

对于 posgresql,当出现异常时,您不能再使用相同的连接提交。您必须先回滚。

就我而言,我使用DatasourceUtils获取当前连接并手动调用connection.rollback() 并调用方法 recruive 重试。

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

附加文件可能对您有所帮助。

我在我的数据库应用程序工具中遇到了这个错误,因为有一个未提交的事务。 我正在尝试运行 select 查询。 所以这给了我这个错误。 您可以修复这些运行

commit;

或者

rollback;

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

将 conn.setAutoCommit(false) 设置为 conn.setAutoCommit(true)

在启动新事务之前提交事务。

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

附加文件可能对您有所帮助。 在此处输入图片说明

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM