Dex*_*Dex 2 transactions ruby-on-rails-3
class Bear < ActiveRecord::Base
def feed!
self.transaction do
raise Exception unless self.foods_eaten << Food.new(:name => "fish")
self.fed_at = Time.now
save!
end
end
end
class Hippo < ActiveRecord::Base
def wash!
self.transaction do
@soap.inventory -= 1
@soap.save!
self.washed_at = Time.now
save!
end
end
end
class ZookeeperController < ApplicationController
def chores
@zookeeper = Zookeeper.find(params[:id])
Animal.transaction do
begin
@hippo.wash!
@bear.feed! # => FAIL AT THIS LINE
@zookeeper.finished_at = Time.now
@zookeeper.save!
redirect_to chores_completed_path
rescue Exception => e
render "new_chores"
end
end
end
end
Run Code Online (Sandbox Code Playgroud)
如果Zookeeper#chores被调用并@bear.feed!失败并引发异常,那么一切都会回滚吗?
也欢迎任何其他有关如何改进此代码的建议。
看来我要做的是手动提高ActiveRecord :: Rollback,否则将无法按预期工作。ActiveRecord :: Rollback是唯一不会导致屏幕转储的选项。http://api.rubyonrails.org/classes/ActiveRecord/Rollback.html
它可以像这样工作是有道理的,但是我并不是直觉上认为它会工作。如果我错了,请纠正我。
因此,新代码如下所示:
class ZookeeperController < ApplicationController
def chores
@zookeeper = Zookeeper.find(params[:id])
Animal.transaction do
begin
@hippo.wash!
@bear.feed! # => FAIL AT THIS LINE
@zookeeper.finished_at = Time.now
@zookeeper.save!
redirect_to chores_completed_path
rescue Exception => e
@_errors = true
render "new_chores"
end
raise ActiveRecord::Rollback if @_errors
end
end
end
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
6359 次 |
| 最近记录: |