事务,什么时候应该被丢弃和回滚

时间:2008-10-12 11:38:32

标签: postgresql transactions autocommit

我正在尝试调试应用程序(在PostgreSQL下)并遇到以下错误: “当前事务中止,命令被忽略”。

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

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

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

使用auto commit false,即使是简单的

,我也会收到PostgreSQL的错误
select * from foo

失败,这让我问,在哪个SQLException(s)是一个被视为无效的“事务”,应该滚动支持还是不用于另一个查询?

  

使用MacOS 10.5,Java 1.5.0_16,PostgreSQL 8.3和JDBC驱动程序8.1-407.jdbc3

2 个答案:

答案 0 :(得分:3)

该错误意味着事务中发送的其中一个查询失败,因此其余查询将被忽略,直到当前事务结束(这将自动为回滚)。对于PostgreSQL,事务已经失败,并且在出现错误之后将在任何情况下回滚,但有一个例外。你必须采取适当的措施,

之一
  1. 弃掉声明并重新开始。
  2. 在事务中使用SAVEPOINT以便能够回到该时间点并尝试其他路径。 (这是例外)
  3. 启用query logging以查看哪个查询失败,以及原因。

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

答案 1 :(得分:1)

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