简体   繁体   English

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

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

I am seeing the following (truncated) stacktrace in the server.log file of JBoss 7.1.1 Final:我在 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

Inspecting the Postgres log file reveals the following statements:检查 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

I am using the Infinispan shipped with JBoss 7.1.1 Final, which is 5.1.2.Final.我使用的是 JBoss 7.1.1 Final 随附的 Infinispan,即 5.1.2.Final。

So this is what I think is happening:所以这就是我认为正在发生的事情:

  • Infinispan attempts to run the SELECT count(*)... statement in order to see if there are any records in the ISPN_MIXED_BINARY_TABLE_configCache ; Infinispan 尝试运行SELECT count(*)...语句以查看ISPN_MIXED_BINARY_TABLE_configCache中是否有任何记录;
  • Postgres, for some reason, does not like this statement.出于某种原因,Postgres 不喜欢这种说法。
  • Infinispan ignores this and plows ahead with the CREATE TABLE statement. Infinispan 忽略了这一点并继续使用CREATE TABLE语句。
  • Postgres barfs because it still thinks it's the same transaction, which Infinispan has failed to roll back, and this transaction is shafted from the first SELECT count(*)... statement. Postgres barfs,因为它仍然认为它是同一个事务,Infinispan 未能回滚,并且这个事务是从第一个SELECT count(*)...语句开始的。

What does this error mean and any idea how to work around it?这个错误是什么意思,知道如何解决它吗?

I got this error using Java and PostgreSQL doing an insert on a table.我使用 Java 和 PostgreSQL 在表上插入时遇到此错误。 I will illustrate how you can reproduce this error:我将说明如何重现此错误:

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

Summary:概括:

The reason you get this error is because you have entered a transaction and one of your SQL Queries failed, and you gobbled up that failure and ignored it.您收到此错误的原因是因为您输入了一个事务并且其中一个 SQL 查询失败,而您吞噬了该失败并忽略了它。 But that wasn't enough, THEN you used that same connection, using the SAME TRANSACTION to run another query.但这还不够,然后您使用相同的连接,使用 SAME TRANSACTION 运行另一个查询。 The exception gets thrown on the second, correctly formed query because you are using a broken transaction to do additional work.在第二个正确形成的查询中抛出异常,因为您正在使用损坏的事务来执行其他工作。 PostgreSQL by default stops you from doing this. PostgreSQL 默认阻止你这样做。

I'm using: 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 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".

My PostgreSQL driver is: postgresql-9.2-1000.jdbc4.jar我的 PostgreSQL 驱动程序是: postgresql-9.2-1000.jdbc4.jar

Using Java version: Java 1.7使用 Java 版本: Java 1.7

Here is the table create statement to illustrate the Exception:这是用于说明异常的 table create 语句:

CREATE TABLE moobar
(
    myval   INT
);

Java program causes the error: 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();
    }   

}

The above code produces this output for me:上面的代码为我生成了这个输出:

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

Workarounds:解决方法:

You have a few options:您有几个选择:

  1. Simplest solution: Don't be in a transaction.最简单的解决方案:不要参与交易。 Set the connection.setAutoCommit(false);设置connection.setAutoCommit(false); to connection.setAutoCommit(true);connection.setAutoCommit(true); . . It works because then the failed SQL is just ignored as a failed SQL statement.它之所以有效,是因为失败的 SQL 只是作为失败的 SQL 语句被忽略。 You are welcome to fail SQL statements all you want and PostgreSQL won't stop you.欢迎您随意使 SQL 语句失败,PostgreSQL 不会阻止您。

  2. Stay being in a transaction, but when you detect that the first SQL has failed, either rollback/re-start or commit/restart the transaction.保持在事务中,但是当您检测到第一个 SQL 失败时,回滚/重新启动或提交/重新启动事务。 Then you can continue failing as many SQL queries on that database connection as you want.然后,您可以根据需要继续在该数据库连接上失败尽可能多的 SQL 查询。

  3. Don't catch and ignore the Exception that is thrown when a SQL statement fails.不要捕获并忽略 SQL 语句失败时抛出的异常。 Then the program will stop on the malformed query.然后程序将在格式错误的查询上停止。

  4. 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.而是获取 Oracle,当您在事务中的连接上的查询失败并继续使用该连接时,Oracle 不会引发异常。

In defense of PostgreSQL's decision to do things this way... Oracle was making you soft in the middle letting you do dumb stuff and overlooking it.在PostgreSQL的决定,这样做事的防御......甲骨文让你在柔和你做愚蠢的东西中间出租,可俯瞰它。

Check the output before the statement that caused current transaction is aborted .导致current transaction is aborted的语句current transaction is aborted之前检查输出。 This typically means that database threw an exception that your code had ignored and now expecting next queries to return some data.这通常意味着数据库抛出了一个您的代码忽略的异常,现在期待下一个查询返回一些数据。

So you now have a state mismatch between your application, which considers things are fine, and database, that requires you to rollback and re-start your transaction from the beginning.因此,您的应用程序(认为一切正常)和数据库(需要您回滚并从头开始重新启动事务)之间存在状态不匹配。

You should catch all exceptions and rollback transactions in such cases.在这种情况下,您应该捕获所有异常并回滚事务。

Here's a similar issue. 这是一个类似的问题。

I think that the best solution is to use java.sql.Savepoint .我认为最好的解决方案是使用java.sql.Savepoint

Before you execute a query which can throw SQLException , use the method Connection.setSavepoint() , and if an exception is thrown you only rollback to this savepoint, not the whole transaction.在执行可以throw SQLException的查询之前,使用方法Connection.setSavepoint() ,如果抛出异常,您只能回滚到这个保存点,而不是整个事务。

Example code:示例代码:

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

   }
}

There's been some work done on the postgresql JDBC Driver, related to this behaviour:已经在 postgresql JDBC 驱动程序上完成了一些与此行为相关的工作:
see https://github.com/pgjdbc/pgjdbc/pull/477https://github.com/pgjdbc/pgjdbc/pull/477

It is now possible, by setting现在可以通过设置

autosave=always
in the connection (see https://jdbc.postgresql.org/documentation/head/connect.html ) to avoid the 'current transaction is aborted' syndroma. 在连接中(参见https://jdbc.postgresql.org/documentation/head/connect.html )避免“当前事务中止”综合症。
Overhead due to handling a savepoint around the statement execution is kept very low (see link above for details). 由于处理语句执行周围的保存点而导致的开销非常低(有关详细信息,请参见上面的链接)。

In Ruby on Rails PG, I had created a migration, migrated my DB, but forgot to restart my development server.在 Ruby on Rails PG 中,我创建了一个迁移,迁移了我的数据库,但忘记重新启动我的开发服务器。 I restarted my server and it worked.我重新启动了我的服务器并且它工作了。

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

Try this COMMIT;试试这个COMMIT;

I run that in pgadmin4.我在 pgadmin4 中运行它。 It may help.它可能会有所帮助。 It has to do with the previous command stopping prematurely它与上一个命令过早停止有关

You need to rollback.你需要回滚。 The JDBC Postgres driver is pretty bad. JDBC Postgres 驱动程序非常糟糕。 But if you want to keep your transaction, and just rollback that error, you can use savepoints:但是如果你想保留你的事务,只是回滚那个错误,你可以使用保存点:

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

Read more here:在此处阅读更多信息:

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

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

I had the same issue but then realised there is a table with the same name in the database.我遇到了同样的问题,但后来意识到数据库中有一个同名的表。 After deleting that I was able to import the file.删除后,我能够导入文件。

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

For me issues was, driver wasn't installed.对我来说问题是,驱动程序没有安装。 I downloaded the driver and pasted in ~/Library/Tableau/Driver(mac) folder & it worked.我下载了驱动程序并粘贴到 ~/Library/Tableau/Driver(mac) 文件夹中,它工作正常。

This is very weird behavior of PostgreSQL, it is even not " in-line with the PostgreSQL philosophy of forcing the user to make everything explicit" - as the exception was caught and ignored explicitly.这是 PostgreSQL 非常奇怪的行为,它甚至不“符合 PostgreSQL 强制用户将所有内容都明确化的哲学”——因为异常被明确地捕获并忽略。 So even this defense does not hold.所以即使是这种防御也不成立。 Oracle in this case behaves much more user-friendly and (as for me) correctly - it leaves a choice to the developer.在这种情况下,Oracle 的行为更加用户友好并且(就我而言)正确 - 它为开发人员留下了选择。

I just encounter the same error.我只是遇到同样的错误。 I was able to figure out the root cause by enabling the log_statement and log_min_error_statement in my local PostgreSQL.通过在本地 PostgreSQL 中启用log_statementlog_min_error_statement ,我能够找出根本原因。

I Referred this我提到了这个

I am using JDBI with Postgres, and encountered the same problem, ie after a violation of some constraint from a statement of previous transaction, subsequent statements would fail (but after I wait for a while, say 20-30 seconds, the problem goes away).我在 Postgres 中使用 JDBI,遇到了同样的问题,即在违反先前事务语句的某些约束后,后续语句将失败(但在我等待一段时间后,比如 20-30 秒,问题消失了)。

After some research, I found the problem was I was doing transaction "manually" in my JDBI, ie I surrounded my statements with BEGIN;...COMMIT;经过一些研究,我发现问题是我在 JDBI 中“手动”进行事务处理,即我用 BEGIN;...COMMIT; 包围了我的语句。 and it turns out to be the culprit!事实证明它是罪魁祸首!

In JDBI v2, I can just add @Transaction annotation, and the statements within @SqlQuery or @SqlUpdate will be executed as a transaction, and the above mentioned problem doesn't happen any more!在JDBI v2中,我只需添加@Transaction注解,@SqlQuery或@SqlUpdate中的语句就会作为一个事务执行,不再出现上述问题!

In my case i was getting this error because my file was corrupt.就我而言,我收到此错误是因为我的文件已损坏。 While iterating the records of files it was giving me the same error.在迭代文件记录时,它给了我同样的错误。

May be in future it will help to anyone.可能在未来它会帮助任何人。 That's the only reason to post this answer.这是发布此答案的唯一原因。

I use spring with @Transactional annotation, and I catch the exception and for some exception I will retry 3 times.我将 spring 与@Transactional注释一起使用,并捕获异常,对于某些异常,我将重试 3 次。

For posgresql, when got exception, you can't use same Connection to commit any more.You must rollback first.对于 posgresql,当出现异常时,您不能再使用相同的连接提交。您必须先回滚。

For my case, I use the DatasourceUtils to get current connection and call connection.rollback() manually.就我而言,我使用DatasourceUtils获取当前连接并手动调用connection.rollback() And the call the method recruive to retry.并调用方法 recruive 重试。

I was working with spring boot jpa and fixed by implementing @EnableTransactionManagement我正在使用 spring boot jpa 并通过实现 @EnableTransactionManagement 进行修复

Attached file may help you.附加文件可能对您有所帮助。

I faced this error in my DB application tool because there is one uncommited transaction.我在我的数据库应用程序工具中遇到了这个错误,因为有一个未提交的事务。 And i'm trying to run a select query.我正在尝试运行 select 查询。 so that gave me this error.所以这给了我这个错误。 You can fix these either running您可以修复这些运行

commit;

or或者

rollback;

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

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

Commit the transactions before initiating a new one.在启动新事务之前提交事务。

I was working with spring boot jpa and fixed by implementing @EnableTransactionManagement我正在使用 spring boot jpa 并通过实现 @EnableTransactionManagement 进行修复

Attached file may help you.附加文件可能对您有所帮助。 在此处输入图片说明

暂无
暂无

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

相关问题 PSQL:当前事务中止,命令被忽略,直到事务块结束 - PSQL: current transaction is aborted, commands ignored until end of transaction block InternalError:当前事务中止,命令被忽略,直到事务块结束 - InternalError: current transaction is aborted, commands ignored until end of transaction block DatabaseError:当前事务被中止,在事务块结束之前忽略命令? - DatabaseError: current transaction is aborted, commands ignored until end of transaction block? Databene Benerator:org.postgresql.util.PSQLException:错误:当前事务中止,命令被忽略,直到事务块结束 - Databene Benerator: org.postgresql.util.PSQLException: ERROR: current transaction is aborted, commands ignored until end of transaction block jOOQ + Spring:PSQLException:当前事务中止,命令被忽略,直到事务结束 - jOOQ + Spring : PSQLException: current transaction is aborted, commands ignored until end of transaction InternalError:当前事务被中止,命令被忽略,直到事务块结束(受UNIQUE约束) - InternalError: current transaction is aborted, commands ignored until end of transaction block ,on UNIQUE constraint django reg extension-当前事务中止,命令被忽略,直到事务块结束 - django reg extend - current transaction is aborted, commands ignored until end of transaction block 错误:当前事务中止,命令被忽略,直到事务块结束—从Aqua Studio导出数据 - ERROR: current transaction is aborted, commands ignored until end of transaction block — export data from Aqua studio psycopg2.errors.InFailedSqlTransaction:当前事务被中止,命令被忽略直到事务块结束 - psycopg2.errors.InFailedSqlTransaction: current transaction is aborted, commands ignored until end of transaction block DatabaseError:当前事务中止,命令被忽略,直到事务块结束-在隐身模式下,但正常情况下没有错误 - DatabaseError: current transaction is aborted, commands ignored until end of transaction block - in incognite mode but no error in normal
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM