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

Jim*_*idy 132 postgresql jboss infinispan

我在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
Run Code Online (Sandbox Code Playgroud)

检查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
Run Code Online (Sandbox Code Playgroud)

我使用的是随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(*)...语句中获得的.

这个错误是什么意思,任何想法如何解决它?

Eri*_*ski 180

我使用Java和postgresql在表上执行插入时出现此错误.我将说明如何重现此错误:

org.postgresql.util.PSQLException: ERROR: 
current transaction is aborted, commands ignored until end of transaction block
Run Code Online (Sandbox Code Playgroud)

摘要:

您收到此错误的原因是您输入了一个事务,并且您的一个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

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

CREATE TABLE moobar
(
    myval   INT
);
Run Code Online (Sandbox Code Playgroud)

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();
    }   

}
Run Code Online (Sandbox Code Playgroud)

上面的代码为我生成了这个输出:

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
Run Code Online (Sandbox Code Playgroud)

解决方法:

你有几个选择:

  1. 最简单的解决方案:不要在交易中.设置connection.setAutoCommit(false);connection.setAutoCommit(true);.它的工作原理是因为失败的SQL只是作为失败的sql语句而被忽略.欢迎您使用所有想要的SQL语句失败,postgresql不会阻止您.

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

  3. 不要捕获并忽略sql语句失败时抛出的异常.然后程序将停止格式错误的查询.

  4. 相反,如果您在事务中的连接上查询失败并继续使用该连接,则Oracle不会抛出异常.

在PostgreSQL的决定,这样做事的防御......甲骨文让你在中间让你做愚蠢的东西,俯瞰柔软.

  • Lol @ Option 4 ...我在Oracle中做了很多开发,最近开始使用Postgres ...... Postgres这样做真的很烦人,现在我们必须真正重写我们的大部分程序,我们正在从Oracle移植到Postgres.为什么没有像第一个让它像甲骨文一样的选项但没有自动提交**? (7认同)
  • 经过一些试验后发现**选项2**是最接近Oracle行为的.如果你需要发出多个更新,并且一个失败不应该停止后续更新,那么当捕获`SQLException`时,只需在`Connection`上调用`rollback()`.[_Anyway_我意识到这符合PostgreSQL强迫用户将一切都明确化的理念,而Oracle则有隐含地处理很多事情的哲学. (2认同)
  • *选项2*包含不可能的分支`或提交/重启事务`.正如我所看到的,在异常之后无法提交.当我尝试提交时 - PostgreSQL执行`rollback` (2认同)
  • https://www.postgresql.org/message-id/op.ur57x9ue33x80h%40insanity.lain.pl 关于这个话题的有趣讨论。如果此问题是由违反约束触发的,PostgreSQL 开发人员建议提前检查冲突(更新/插入前查询)或使用 `savepoints` 回滚到更新/插入前的点。有关示例代码,请参阅 /sf/answers/2004839021/。 (2认同)

vye*_*rov 24

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

因此,现在您的应用程序与数据库之间存在状态不匹配,这需要您从头开始回滚并重新启动事务.

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

这是一个类似的问题.


Kig*_*lip 17

尝试这个COMMIT;

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

  • 为我解决了问题) (2认同)

小智 9

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

   }
}
Run Code Online (Sandbox Code Playgroud)


Nav*_*ngh 6

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

commit;
Run Code Online (Sandbox Code Playgroud)

或者

rollback;
Run Code Online (Sandbox Code Playgroud)


Mar*_*o L 5

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

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

在这里阅读更多内容:

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


the*_*tto 5

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


小智 5

The reason for this error is that there are other database before the wrong operation led to the current database operation can not be carried out\xef\xbc\x88i use google translation to translate my chinese to english\xef\xbc\x89

\n


小智 5

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

现在可以通过设置

自动保存=总是
连接中(请参阅https://jdbc.postgresql.org/documentation/head/connect.html),以避免“当前事务中止”的症状。
由于处理语句执行周围的保存点而导致的开销保持得很低(有关详细信息,请参见上面的链接)。

  • IMO,这应该被接受这个问题的答案。此外,与“autosave=always”一起,建议设置“cleanupSavepoints=true”以避免耗尽共享缓冲区。 (3认同)