我想在我的一个控制器创建方法中添加一个begin ... rescue block,以便记录更好的信息并构造正确的错误消息以返回给客户端。救援以任何方式“中断”回滚过程吗?
我假设rails自动进行回滚。它什么时候发生?在我获得救援条款时,它已经发生了吗?
我在Dreamhost上使用mySQL,我认为他们使用的是innoDB。
答案 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
由于