【问题标题】:Suspend transaction in Postgres在 Postgres 中暂停事务
【发布时间】:2017-11-12 20:03:18
【问题描述】:

我看到另一个数据库系统提供暂停transaction。当前事务保持不变,但在允许您的代码与数据库一起使用以立即对行进行永久更改时被搁置。然后你可以恢复事务,继续你离开的地方,使用相同的锁和其他事务保护,就好像你从未中断它一样。

例如,假设客户在交易中下订单。在该交易期间,客户注意到他们的电话号码需要更新,因此我们更改了该数据。接下来,客户决定取消尚未完成的订单。订单回滚会带来意想不到的后果,即取消电话号码更改。如果我们可以的话,那就太好了:

  1. 暂停订单的交易。
  2. 更新电话号码,提交到数据库。
  3. 恢复订单的交易。

有什么方法可以暂停Postgres 中的事务吗?在JDBC?

【问题讨论】:

  • 有趣的问题......感谢您对我的回答非常有帮助的编辑!

标签: postgresql transactions suspend


【解决方案1】:

如果一个事务不能继续,它必须回滚。

如果您的交易有一个您不知道如何进行的点,那么您的交易逻辑有缺陷,您需要重新组织它 - 或者拆分为多个交易(或子交易,也就是保存点),或者取出不属于事务逻辑的部分。

有什么方法可以暂停 Postgres 中的事务吗?

不,没有这样的事情。并且数据完整性原则是时间无条件的。

【讨论】:

    【解决方案2】:

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

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

    在第二个连接上执行您的单独工作并关闭。第一个连接仍处于打开状态并保持相同的状态。第一个连接中的任何活动事务都将保留。

    【讨论】:

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

    没有。

    最接近的东西是

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

    • savepoints:这允许“嵌套事务”,其中部分事务可以回滚。

    这些都不完全符合您的要求。似乎我们的示例有两个操作根本不需要属于同一事务,因为电话号码更新似乎与订单的成功无关。 (此外,长时间运行的事务是一个坏主意……您的订单可能应该是一个没有长时间运行事务的状态机。)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-10-31
      • 2010-12-20
      • 2013-08-15
      • 1970-01-01
      • 2012-08-05
      • 1970-01-01
      相关资源
      最近更新 更多