2008-10-12 82 views
1

我试图调试一个应用程序(在PostgreSQL下)并遇到以下错误: “当前事务被中止,命令被忽略”。交易,何时应该丢弃和回滚

据我所知,“事务”只是一个与底层数据库连接有关的概念。

如果连接的自动提交为“false”,那么只要没有失败,就可以通过相同的语句执行查询。在这种情况下,你应该回滚。

如果自动提交是“真”,那么只要您的所有查询都被视为原子,则无关紧要。

使用自动提交假的,我在PostgreSQL中,即使一个简单的

select * from foo 

失败了,这让我问,其下的SQLException(S)是一种“交易”视为无效,并应得到上述错误滚动支持或不用于另一个查询?

using MacOS 10.5, Java 1.5.0_16, PostgreSQL 8.3 with JDBC driver 8.1-407.jdbc3

回答

3

该错误意味着在一个事务中发送的一个查询失败了,所以查询的其余部分被忽略,直到当前的事务(将自动回滚)结束。对于PostgreSQL而言,事务失败了,并且在发生错误之后的任何情况下都会回滚,但有一个例外。你必须采取适当的措施,其中之一

  1. 丢弃声明并重新开始。
  2. 使用SAVEPOINT s在交易中能够回到那个时间点并尝试另一条路径。 (这是例外)

启用query logging查看哪个查询是失败的,以及为什么。

在任何情况下,对于您的问题的确切答案是任何SQLException应该意味着发送结束事务时发生回滚,即发出COMMIT或ROLLBACK(或END)时。这就是它的工作原理,如果你使用保存点,你仍然会受到相同的规则约束,你只能回到你保存的地方并尝试其他的东西。

+0

感谢您的澄清。 我做了一些测试,发现当PostgreSQL *下的auto commit设置为false时,如果发生异常,您必须*回滚以执行下一条语句(您可以重复使用现有的语句)。例如,*不是以mySQL为例。 – qnoid 2008-10-12 22:28:17

+0

是的,这是它的工作原理,我不明白在答案中还有什么不清楚的地方。我没有提到它不像其他DBMS那样?为什么这会相关? :)。顺便说一句,你必须做的是完成当前事务或到达一个非错误的保存状态。 – 2008-10-13 08:31:55

1

这似乎是大多数其他DBMS不共享的PostgreSQL的特性行为。一般来说(在PostgreSQL之外),你可以让一个操作由于错误而失败,然后在同一个事务中,可以尝试替代的操作,以补偿错误。一个例子:考虑合并(插入/更新)操作。如果尝试插入新记录但发现它已存在,则可以切换到更改现有记录的UPDATE操作。这在所有主DBMS中都可以正常工作。我不确定它在PostgreSQL中无法正常工作,但我在别处以及在这个问题中看到的描述表明,当尝试INSERT意味着事务中的任何进一步活动注定也会失​​败。这是最严厉的,最糟糕的是“无法使用”。