首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >PSQLException:当前事务被中止,命令被忽略,直到事务块结束

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

Stack Overflow用户
提问于 2012-05-01 15:11:22
回答 20查看 420.6K关注 0票数 245

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

代码语言:javascript
运行
复制
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日志文件会发现以下语句:

代码语言:javascript
运行
复制
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(*)...语句中传递出来的。

这个错误意味着什么,以及如何绕过它?

EN

回答 20

Stack Overflow用户

发布于 2012-10-27 20:01:39

--我使用Java和PostgreSQL对一个表进行插入,得到了这个错误。我将演示如何重现此错误:

代码语言:javascript
运行
复制
org.postgresql.util.PSQLException: ERROR: 
current transaction is aborted, commands ignored until end of transaction block

摘要:

您收到此错误的原因是您输入了一个事务,其中一个SQL查询失败了,而您抢占了该错误并忽略了它。但是这还不够,然后使用相同的连接,使用相同的事务来运行另一个查询。在第二个格式正确的查询中会抛出异常,因为您正在使用一个损坏的事务来执行其他工作。默认情况下,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语句:

代码语言:javascript
运行
复制
CREATE TABLE moobar
(
    myval   INT
);

Java程序导致错误:

代码语言:javascript
运行
复制
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();
    }   

}

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

代码语言:javascript
运行
复制
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:

你有几个选择:

  1. 最简单的解决方案:不要在事务中。将connection.setAutoCommit(false);设置为connection.setAutoCommit(true);。它可以工作,因为失败的SQL只是作为失败的SQL语句被忽略。欢迎您随心所欲地失败SQL语句,而且PostgreSQL不会阻止您。
  2. 保持在事务中,但是当您检测到第一个SQL失败时,要么回滚/重新启动,要么提交/重新启动事务。然后,您可以继续在该数据库连接上执行任意数量的SQL查询。
  3. 不要捕捉并忽略SQL语句失败时引发的异常。然后,程序将停止对格式错误的查询。
  4. 相反,当您在事务中的连接上失败并继续使用该连接时,Oracle不会抛出异常。

为了维护PostgreSQL的决定.甲骨文让你在中间变得软弱,让你做些愚蠢的事情,却忽略了它。

票数 288
EN

Stack Overflow用户

发布于 2012-05-01 15:36:04

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

因此,现在您的应用程序(它认为一切都很好)和数据库之间存在状态不匹配,这要求您从一开始就回滚并重新启动事务。

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

下面是一个类似的问题。

票数 42
EN

Stack Overflow用户

发布于 2015-02-21 00:30:19

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

在执行可以throw SQLException的查询之前,请使用Connection.setSavepoint()方法,如果抛出异常,则只回滚到该保存点,而不是整个事务。

示例代码:

代码语言:javascript
运行
复制
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) {}

   }
}
票数 22
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/10399727

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档