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





jboss infinispan (13)


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

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

这个错误意味着什么以及任何想法如何解决它?




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

因此,现在您的应用程序(它认为事情没有问题)和数据库之间的状态不匹配,需要您从头开始回滚并重新启动事务。

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

这是一个类似的问题。







你需要回滚。 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得到修复




我得到这个错误使用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

下面是表格创建语句来说明例外情况:

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在事务中的连接失败并且继续使用该连接时不会引发异常。

为了防止postgresql以这种方式做事情的决定... Oracle让你在中间变得柔软,让你做愚蠢的事情并忽略它。




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




这是PostgreSQL的非常奇怪的行为,它甚至不符合强制用户将所有事情明确化的PostgreSQL理念 - 因为异常被明确地捕获和忽略。 所以即使这个防守也不成立。 在这种情况下,Oracle的行为更加方便用户使用(正如我一样) - 这给开发人员留下了一个选择。




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




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







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

   }
}



如果您使用Debian,当您安装postgresql包时,它将使用您的默认语言环境来创建template1数据库。 如果尚未将操作系统配置为使用UTF-8作为默认语言环境,则会遇到此错误。

除了上述解决方案之外,如果您正在进行新安装并且没有活动数据库,则可以删除postgresql包并将默认语言环境设置为UTF-8。 此方法的优点是您可以在将来创建数据库时省略区域设置信息。

dpkg-reconfigure locales

如果看不到所需的区域设置,请安装locales-all软件包

apt-get install locales-all

然后删除postgresql

apt-get remove --purge postgresql-<version>

然后重新安装或更好地升级到最新版本,而不是Debian stable







postgresql jboss infinispan