【问题标题】:ActiveRecord, MySQL, and nested transactions -- what's the behavior?ActiveRecord、MySQL 和嵌套事务——行为是什么?
【发布时间】:2011-06-25 03:27:19
【问题描述】:

Rails 使用savepoints 实现与 MySQL 的嵌套事务,据我了解,就原子数据更改而言,其语义与实际嵌套事务相同。

  1. 这是真的吗?
  2. 在代码中的任意时间调用“保存”会怎样?交易仍然保持开放,直到区块结束,对吧?使用嵌套事务/保存点时的行为是否有任何差异?
  3. 还有什么需要注意的吗?
  4. [故意煽动火焰战争]我应该切换到PostgresSQL吗?

【问题讨论】:

    标签: mysql ruby-on-rails activerecord transactions savepoints


    【解决方案1】:
    1. 是的,这是真的,唯一具有真正嵌套事务的数据库是 MS SQL Server

    2. 是的,即使您在任意时间调用 save,事务也会保持打开状态,但是,如果在嵌套事务内部引发回滚异常,则不会导致外部事务的全局回滚(参见 #3保存点管理)。

    3. 您可以将 Model.transaction(:requires_new => true) 传递给创建子事务,这可能是您所期望的行为,否则您将无法控制嵌套事务不服从嵌套回滚。此外,人们有时会忘记模型回调都在 1 个事务中执行,因此回调中的任何事务都是嵌套事务。

    4. 您并没有真正挑起一场激烈的战争,PostgresSQL 也没有嵌套事务(它也使用保存点),它们都是很棒的数据库。

    【讨论】:

    • 您能否详细说明第 3 点? “控制嵌套事务”是什么意思
    • 如果您不使用“requires_new”,则回滚点是父事务的开始,而不是“子事务”,因为保存点如何与 AR 一起使用。 api.rubyonrails.org/classes/ActiveRecord/Transactions/…
    • 我明白了。那么,如果(a)保存或(b)引发异常,在嵌套事务中有或没有“requires_new”,行为有何不同?
    • 如果您不使用“requires_new”,那么任何引发的异常(即使是引发 10 个子事务深度的异常)都会导致事务恢复到创建的第一个事务。如果您使用“requires_new => true”,那么它将创建一个新的保存点,然后允许任何异常恢复到最后一个真正的保存点的点(或者当您在子事务中调用“requires_new”时)
    【解决方案2】:

    据我所知,Mysql 的嵌套事务依赖于 MySQL 5+ 中的 Savepoints 功能。如果您是 Rails 2.3.2+ 和 Mysql 5+,看起来它应该可以正常工作。

    但是,嵌套事务管理起来可能非常混乱。如果您依靠它来清理您正在做的事情并将工作流程分解成更简单的东西(恕我直言),您可能需要考虑您的设计选择。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2010-11-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-02-09
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多