【问题标题】:When do transactions start when using (restful) rails使用(restful)rails 时事务何时开始
【发布时间】:2010-09-12 13:40:27
【问题描述】:

是不是整个restful动词都在一个包罗万象的事务之下?也就是说,如果我在处理 UPDATE、DELETE 或 CREATE 操作的任何时候在验证或回调中引发错误,我在以前的回调中执行的每个数据库操作是否也会回滚?简而言之,在任何回调或验证上引发错误是否会使数据库中对该动词操作完全不发生任何更改?

【问题讨论】:

    标签: ruby-on-rails ruby rest transactions


    【解决方案1】:

    一些方法(创建、销毁)会立即进入数据库。事务通过对从 ActiveRecord 派生的类使用事务方法进行,如下所示:

    Student.transaction do
      Course.transaction do
        course.enroll(student)
        student.units += course.units
      end
    end
    

    (这个例子是针对多个数据库的,对于单个数据库,你只需要一个事务。)

    然后您可以回滚这些事务,事务中抛出的异常会在回滚后传播。

    这取决于具有事务的数据库。

    注意:保存和销毁都包含在事务中。

    【讨论】:

    • 你不需要像这样嵌套事务。对 .transaction 的任何调用都会传递给 ActiveRecord::Base。你实际上只是调用 ActiveRecord::Base.transaction 两次
    • 这是来自 rails 文档的示例。
    • 啊!我看到它是多个数据库所必需的。已更新。
    【解决方案2】:

    是不是整个restful动词都在一个包罗万象的事务之下?

    没有

    如果我在处理 UPDATE、DELETE 或 CREATE 操作的任何时候在验证或回调中引发错误,我在之前的回调中执行的每个数据库操作是否也会回滚?

    没有。

    在任何回调或验证上引发错误是否会导致该动词操作的数据库中根本没有发生任何更改?

    没有。

    如果您想要这种行为,您可以在控制器中显式创建事务(请参阅其他用户提供的示例),或使用 around_filter 将行为附加到您的所有休息操作。

    【讨论】:

      【解决方案3】:

      默认情况下,事务中没有编写数据库代码,您需要在代码中告诉它这样做。

      def create
        Model.transaction do
          Model.create!(params[:model])
          Model.association.create!(params[:association])
        end
        rescue ActiveRecord::RecordNotSaved, ActiveRecord::RecordInvalid
          flash[:notice] = "That record could not be saved."
          render :action => "new"
      end
      

      使用#create!方法将尝试保存记录,如果失败,它们将引发异常,然后回滚已在事务块内执行的任何代码。

      如果您不挽救该操作,您将被重定向到(我认为)公共目录中的 405.html(如果存在)。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2016-09-28
        • 1970-01-01
        • 2012-04-02
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-12-23
        相关资源
        最近更新 更多