Postgres中的挂起事务

3
我看到另一个数据库系统提供了暂停事务的功能。当前的事务保持不变,但是在您的代码允许与数据库交互以对行进行立即永久更改时被暂停。然后,您可以恢复事务,继续之前离开的地方,具有相同的锁定和其他事务保护,就像您从未中断过一样。
例如,假设客户正在进行交易下订单。在该交易期间,客户注意到他们的电话号码需要更新,因此我们更改了该数据。接下来,客户决定取消尚未完成的订单。订单回滚会意外地撤消电话号码更改。因此,如果我们能够:
  1. 暂停订单的事务。
  2. 更新电话号码,提交到数据库。
  3. 恢复订单的事务。
Postgres中是否有一种暂停事务的方法?在JDBC中是否有一种暂停事务的方法?

有趣的问题...感谢您对我的答案进行非常有帮助的编辑! - GhostCat
3个回答

1

不是的。

最接近的可能是

  • 准备事务:这允许(在某些条件下)保存事务,然后稍后回滚或提交。

  • 保存点:这允许“嵌套事务”,其中事务的某些部分可以回滚。

但这两个都不完全符合您的要求。看起来我们的示例有两个操作根本不需要成为同一事务的一部分,因为更新电话号码似乎与订单成功无关。(此外,长时间运行的事务是个坏主意...您的订单应该是一个实现了无需长时间运行事务的状态机。)


1

如果事务无法继续,它必须回滚。

如果您的事务在某个点上不知道如何继续,则您的事务逻辑存在缺陷,需要重新组织它 - 要么拆分成多个事务(或子事务,也称为保存点),要么取出不属于事务逻辑的部分。

有没有一种方法可以在Postgres中暂停事务?

不,没有这样的东西。数据完整性原则是无条件的。


0

解决方法 - 打开第二个连接

在JDBC中,您可以打开第二个连接到数据库。

在第二个连接上进行单独的工作并关闭。第一个连接仍然保持打开状态,并保持其原始状态。任何在第一个连接中活动的事务都将保持不变。


这种情况经常会遇到死锁,当第二个事务需要执行被第一个事务锁定的操作时,就无法继续进行。只有在这两个事务之间没有依赖关系时才不会发生,但这意味着你的第一个事务是错误的,因为它试图首先做一些不应该做的事情。对数据库设计问题的变通方法通常是一个坏主意。 - vitaly-t
@vitaly-t 我在问题中添加了一个示例场景。在事务中开始客户订单,顺便我们决定更新电话号码,然后客户取消新但不完整的订单。当我们回滚订单时,我们无意中也回滚了电话号码。正如您所提到的,这是一个设计问题吗?对我来说,这似乎是一个合理的问题和解决方案,但我愿意听取其他立场的意见。 - Basil Bourque
1
你的例子混淆了业务交易和数据库事务,这两者是完全不同的东西。 - vitaly-t
@vitaly-t 很不幸,一些应用程序会混淆这些并在用户在GUI界面中点击时保持交易处于打开状态。 正确的方法是修复GUI界面。 如果无法实现此操作,GUI界面应锁定它触及的每一行,以便其他人必须等待。 否则,由于某些事务最终会失败,因此可能会丢失某些工作。 - Mikko Rantalainen

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接