使用(restful)rails 时事务何时开始

Posted

技术标签:

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

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

【问题讨论】:

【参考方案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(如果存在)。

【讨论】:

以上是关于使用(restful)rails 时事务何时开始的主要内容,如果未能解决你的问题,请参考以下文章

何时使用 Mongrel 作为 Rails 应用程序的 Web 服务器?

从 Rails 5 开始,何时需要手动设置 :inverse_of?

sqlite3 事务调整页面缓存等待锁代码

应用程序管理的 JPA,何时需要事务

Backbone.js 前端和 RESTful Rails 后端?

使用 RESTful 身份验证插件进行 Ruby on Rails 功能测试