如果我使用begin ... rescue,rails会做回滚吗?

时间:2010-04-23 17:41:54

标签: ruby-on-rails exception-handling transactions

我想在我的一个控制器创建方法中添加一个begin ... rescue block,以便记录更好的信息并构造正确的错误消息以返回给客户端。救援以任何方式“中断”回滚过程吗?

我假设rails自动进行回滚。它什么时候发生?在我获得救援条款时,它已经发生了吗?

我在Dreamhost上使用mySQL,我认为他们使用的是innoDB。

4 个答案:

答案 0 :(得分:20)

我一直在试验这个。看起来如果你的救援捕获了导致回滚的异常,那么已经发生的事务部分就会被提交。就我而言,我希望数据库回滚到事务开始之前的状态,但我仍然希望处理异常。

我最终得到了这个:

self.transaction do
  first_operation
  begin
    operation_that_might_violate_db_constraint
  rescue ActiveRecord::RecordNotUnique
      #deal with the error
      raise ActiveRecord::Rollback #force a rollback
  end
end

raise ActiveRecord::Rollback部分确保事务完全回滚。没有它,first_operation的更改最终会被提交。

ActiveRecord :: Rollback是一种特殊的异常,它不会在事务级别之上冒泡,所以你不会得到一个呈现错误页面的未捕获异常。

我不确定这是采用黄金标准的方法,但似乎有效。

答案 1 :(得分:0)

仅使用begin ... rescue不足以回滚事务。你需要使用:

ModelName.transaction do 
end

这是在保存调用时明确完成的,因此所有回调都会一起执行。你在救援区有什么例外?你在回应什么?什么样的错误?

答案 2 :(得分:-1)

不处理回滚。

例如:

create_table "helps", :force => true do |t|
    t.string   "title",                           :null => false
    t.text     "content"
end

#Rails console
Help.transaction do
  Help.create! title: "aaa"
  begin
    Help.create! content: "111"
  rescue
    p "create error."
  end
  Help.create! title: "bbb"
end

#get this
>> "create error."
Help.count
>> 2

答案 3 :(得分:-3)

您还可以使用 ActiveRecord :: Base.transaction 尝试使用回滚,捕获和渲染创建方法的答案: - Click Here

由于