我在 JBoss 7.1.1 Final 的 server.log 文件中看到以下(截断的)堆栈跟踪:
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(*)... 语句中产生的。
这个错误是什么意思,知道如何解决它吗?
PSQLException: current transaction is aborted...
(25P02
),也可能搜索 JPA
或 Hibernate
。最后,这是由于我们的(很好!)Logback 使用由 toString()
重载的 DAO 对象提供,导致错误并被很好地吞下(但我不小心没有注意到):log.info( "bla bla: {}", obj )
产生了 < b>bla bla: [FAILED toString()]
。将其更改为 log.info( "bla bla: {}", String.valueOf( obj )
使其为空安全,但不会吞下它,从而使事务在不相关的查询上失败。
我使用 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
解决方法:
你有几个选择:
最简单的解决方案:不要进行交易。设置连接。setAutoCommit(false);到 connection.setAutoCommit(true);。它之所以有效,是因为失败的 SQL 只是作为失败的 SQL 语句而被忽略。欢迎你让 SQL 语句失败,PostgreSQL 不会阻止你。留在事务中,但是当您检测到第一个 SQL 失败时,回滚/重新启动或提交/重新启动事务。然后,您可以根据需要继续在该数据库连接上失败尽可能多的 SQL 查询。不要捕获并忽略 SQL 语句失败时引发的异常。然后程序将在格式错误的查询上停止。取而代之的是 Oracle,当您对事务中的连接的查询失败并继续使用该连接时,Oracle 不会引发异常。
为了捍卫 PostgreSQL 以这种方式做事的决定……Oracle 让你在中间变得软弱,让你做愚蠢的事情并忽略它。
在导致 current transaction is aborted
的语句之前检查输出。这通常意味着数据库抛出了您的代码忽略的异常,现在期望下一个查询返回一些数据。
因此,您现在认为一切正常的应用程序和数据库之间存在状态不匹配,这需要您从头回滚并重新启动事务。
在这种情况下,您应该捕获所有异常并回滚事务。
SQL
,您将有一些字段来使用 PostgreSQL 可扩展性消除问题。
我认为最好的解决方案是使用 java.sql.Savepoint
。
在执行可以 throw 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) {}
}
}
在 postgresql JDBC 驱动程序上已经完成了一些与此行为相关的工作:
请参阅 https://github.com/pgjdbc/pgjdbc/pull/477
现在可以通过设置
autosave=always
https://jdbc.postgresql.org/documentation/head/connect.html
在 Ruby on Rails PG 中,我创建了一个迁移,迁移了我的数据库,但忘记重新启动我的开发服务器。我重新启动了我的服务器并且它工作了。
试试这个COMMIT;
我在 pgadmin4 中运行它。它可能会有所帮助。它与上一个命令过早停止有关
这个错误的原因是之前有其他数据库错误操作导致当前数据库操作无法进行(我用google翻译把我的中文翻译成英文)
你需要回滚。 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
我有同样的问题,但后来意识到数据库中有一个同名的表。删除后,我能够导入文件。
如果卷上的磁盘空间不足,可能会发生这种情况。
对我来说问题是,驱动程序没有安装。我下载了驱动程序并粘贴到 ~/Library/Tableau/Driver(mac) 文件夹中,它工作正常。
这是 PostgreSQL 非常奇怪的行为,它甚至不符合 PostgreSQL 强制用户明确所有内容的哲学——因为异常被明确地捕获和忽略。因此,即使这种辩护也不成立。在这种情况下,Oracle 的行为更加用户友好并且(就我而言)正确 - 它为开发人员留下了选择。
我将 JDBI 与 Postgres 一起使用,遇到了同样的问题,即在违反先前事务语句的某些约束后,后续语句将失败(但在我等待一段时间后,比如 20-30 秒,问题就消失了)。
经过一番研究,我发现问题是我在 JDBI 中“手动”执行事务,即我用 BEGIN;...COMMIT; 包围了我的语句。原来是罪魁祸首!
在JDBI v2中,我只需添加@Transaction注解,@SqlQuery或@SqlUpdate中的语句将作为事务执行,不再出现上述问题!
就我而言,我收到此错误是因为我的文件已损坏。在迭代文件记录时,它给了我同样的错误。
将来可能会对任何人都有帮助。这是发布此答案的唯一原因。
我使用带有 @Transactional
注释的 spring,我捕获了异常,对于某些异常,我将重试 3 次。
对于 posgresql,当出现异常时,您不能再使用相同的 Connection 提交。您必须先回滚。
就我而言,我使用 DatasourceUtils
获取当前连接并手动调用 connection.rollback()
。并调用recruive方法重试。
将隔离级别从可重复读取更改为已提交读取。
我正在使用 spring boot jpa 并通过实现 @EnableTransactionManagement 来修复
附件可能对您有所帮助。
我正在使用 spring boot jpa 并通过实现 @EnableTransactionManagement 来修复
https://i.stack.imgur.com/Gd4FP.png
SQLException
时调用Connection
上的rollback()
。 [无论如何我意识到这符合 PostgreSQL 强制用户将所有事情都明确化的理念,而 Oracle 的理念是隐式处理很多事情。]or commit/restart the transaction
。正如我所看到的,在异常之后没有办法提交。当我尝试提交时 - PostgreSQL 执行rollback
psql
直接复制。 (1) 开始一个事务,(2) 发出一些有效的语句,(3) 发出一个无效的语句,(4) 提交 --> psql 将回滚而不是提交。savepoints
回滚到更新/插入之前的点。有关示例代码,请参阅 stackoverflow.com/a/28640557/14731。