PSQLException:当前事务中止,在事务块结束之前忽略命令

我在JBoss 7.1.1 Final的server.log文件中看到以下(截断的)stacktrace:

原因:org.postgresql.util.psql异常:
错误:当前事务被中止,在结束之前忽略命令
事务块
位于org.postgresql.core.v3.QueryExecutorImpl.receiveErrorResponse(QueryExecutorImpl.java:2102)
位于org.postgresql.core.v3.QueryExecutorImpl.processResults(QueryExecutorImpl.java:1835)
位于org.postgresql.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.java:257)
位于org.postgresql.jdbc2.AbstractJdbc2Statement.execute(AbstractJdbc2Statement.java:512)
位于org.postgresql.jdbc2.AbstractJdbc2Statement.executeWithFlags(AbstractJdbc2Statement.java:374)
位于org.postgresql.jdbc2.AbstractJdbc2Statement.executeUpdate(AbstractJdbc2Statement.java:302)
在sun.reflect.NativeMethodAccessorImpl.invoke0(本机方法)[rt.jar:1.6.0_23]
在sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)[rt.jar:1.6.023]
在sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)[rt.jar:1.6.023]
在java.lang.reflect.Method.invoke(Method.java:597)[rt.jar:1.6.023]
位于org.postgresql.ds.jdbc23.AbstractJdbc23PooledConnection$StatementHandler.invoke(AbstractJdbc23PooledConnection.java:455)
位于org.jboss.jca.adapters.jdbc.WrappedStatement.executeUpdate(WrappedStatement.java:371)的$Proxy49.executeUpdate(未知源代码)
位于org.infinispan.loaders.jdbc.TableManipulation.executeUpdateSql(TableManipulation.java:154)[infinispan-cachestore-jdbc-5.1.2.FINAL.jar:5.1.2.FINAL]
... 154多

检查Postgres日志文件会显示以下语句:

语句:从ISPN\u MIXED\u BINARY\u TABLE\u configCache中选择count(*)
错误:当前事务中止,在事务块结束之前忽略命令
语句:创建表ISPN\u MIXED\u BINARY\u TABLE\u configCache(ID\u COLUMN VARCHAR(255)NOT NULL,DATA\u COLUMN BYTEA,TIMESTAMP\u COLUMN BIGINT,主键(ID\u COLUMN))
错误:字符22处不存在“ispn\u混合\u二进制\u表\u配置缓存”关系

我使用的是JBoss 7.1.1 Final附带的Infinispan,即5.1.2.Final

这就是我认为正在发生的事情:

  • Infinispan尝试运行SELECT count(*)…语句,以查看ISPN\u MIXED\u BINARY\u TABLE\u configCache中是否有任何记录
  • 出于某种原因,博士后不喜欢这种说法
  • Infinispan忽略了这一点,继续执行createtable语句
  • Postgres之所以会呕吐,是因为它仍然认为这是同一个事务,Infinispan无法回滚,而该事务是从第一个SELECT count(*)…语句开始的

这个错误意味着什么?你知道如何解决它吗

我使用Java和PostgreSQL在表上执行插入操作时遇到了这个错误。我将说明如何重现此错误:

org.postgresql.util.psql异常:错误:
当前事务被中止,在事务块结束之前忽略命令

摘要:

出现此错误的原因是,您输入了一个事务,但其中一个SQL查询失败,而您将该失败排除在外并忽略了它。但这还不够,然后使用相同的连接,使用相同的事务运行另一个查询。在第二个格式正确的查询上引发异常,因为您正在使用一个中断的事务来执行其他工作。默认情况下,PostgreSQL会阻止您执行此操作

我正在使用:PostgreSQL 9.1.6 on x86_64-redhat-linux-gnu,由gcc(gcc)4.7.2 20120921(redhat 4.7.2-2)编译,64位

我的PostgreSQL驱动程序是:PostgreSQL-9.2-1000.jdbc4.jar

使用Java版本:Java1.7

下面是table create语句来说明异常情况:

创建表moobar
(
myval INT
);

Java程序导致错误:

public void postgresql\u insert()
{
尝试
{
connection.setAutoCommit(false);//开始事务。
语句Statement=connection.createStatement();
System.out.println(“开始执行语句.执行”);
语句。执行(
&“插入到moobar值中(”+
&“此SQL语句失败,并且”+
&“被捕获物吞掉了,okfine”)”;
//上面这行抛出了一个异常,因为我们试图死记硬背
//一个字符串转换成一个Int。我想,会发生什么呢
//例外,忽略它,就像什么都没有错一样。
//但请记住,我们正在进行交易!所以请继续阅读。
System.out.println(“statement.execute done”);
语句。close();
}
捕获(SQLException sqle)
{
System.out.println(“继续使用卡车,继续使用”+
&“最后一次连接是因为什么可能出错?”;
}
试一试{
语句Statement=connection.createStatement();
语句.executeQuery(“从moobar中选择*”);
//此SQL格式正确,但它会抛出
//“事务已中止”SQL异常,原因是:
//你在交易中。
//B.您运行的SQL语句失败。
//C.您没有对受影响的连接执行回滚或提交。
}
捕获(SQLException sqle)
{
printStackTrace();
}   
}

以上代码为我生成此输出:

开始执行语句。执行
继续使用truckin,继续使用最后一个连接,因为会出现什么问题?
org.postgresql.util.PSQLException:
错误:当前事务被中止,命令被忽略,直到
事务块结束

解决方法:

您有几个选择:

  1. 最简单的解决方案:不要在交易中。设置连接。设置自动提交(false)到连接。设置自动提交(true)。它之所以有效,是因为失败的SQL只是作为失败的SQL语句被忽略。欢迎您随意让SQL语句失败,PostgreSQL不会阻止您

  2. 保持在事务中,但当检测到第一个SQL失败时,请回滚/重新启动或提交/重新启动事务。然后,您可以继续在该数据库连接上失败任意多个SQL查询

  3. 不要捕获并忽略SQL语句失败时引发的异常。然后程序将在格式错误的查询上停止

  4. 取而代之的是,当您对事务中的连接进行查询失败并继续使用该连接时,Oracle不会引发异常

为支持PostgreSQL这样做的决定。。。Oracle 让你在中间柔软,让你做愚蠢的东西,忽略它。

发表评论