我使用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计数(*)…语句。
概要:
得到此错误的原因是因为您输入了一个事务,并且您的一个SQL查询失败,并且您忽略了该失败并忽略它。但这还不够,所以你使用同样的连接,使用SAME TRANSACTION来运行另一个查询。第二个正确形成的查询会抛出异常,因为您正在使用损坏的事务来执行其他工作。 Postgresql默认阻止你这样做。
我使用:Postgresql 9.1.6 on x86_64-redhat-linux-gnu,由gcc(GCC)编译4.7.2 20120921(Red Hat 4.7.2-2),64位“。
我的postgresql驱动是:postgresql-9.2-1000.jdbc4.jar
使用java版本:Java 1.7
这里是表的create语句来说明异常:
@H_404_1@CREATE TABLE moobar ( myval INT );Java程序导致错误:
@H_404_1@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(); } } @H_404_1@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解决方法:
您有几个选项:
>最简单的解决方案:不要在事务中。设置connection.setAutoCommit(false);到connection.setAutoCommit(true);.它工作原因,因为失败的sql只是被忽略作为失败的sql语句。你欢迎失败sql语句所有你想要和postgresql不会阻止你。
>保持在一个事务中,但是当您检测到第一个sql失败时,回滚/重新启动或提交/重新启动事务。然后,您可以根据需要在该数据库连接上继续失败尽可能多的SQL查询。
>不捕获并忽略在sql语句失败时抛出的异常。然后程序将停止在格式不正确的查询。
>获取Oracle,Oracle不会在事务中的连接上的查询失败并继续使用该连接时抛出异常。
在保护postgresql的决定做这样的事情…甲骨文让你软中间让你做蠢的东西,俯瞰它。