是否可以设置一个Rails应用程序,以便所有控制器操作都自动用事务包装,如果出现无法解决的异常,该事务会自动回滚?
我正在开发一个Rails 3应用程序,目前用于进行大量数据库更改的相当棘手的操作。而且我经常弄错了很多次!过了一会儿,我意识到我的代码没有工作,因为我的数据库中的数据不一致。
我可以很容易地用事务包装它(这是一个需要一个明确的实例!)。然而,它让我想到,至少在开发过程中,将这个想法应用于每个控制器动作都是有用的。
假设有可能,这有什么缺点吗?
答案 0 :(得分:17)
有关信息,我在应用程序控制器中使用around_filter执行了此操作:
around_filter :wrap_in_transaction
def wrap_in_transaction
ActiveRecord::Base.transaction do
yield
end
end
这只会在任何未处理的异常上回滚事务,并重新引发异常。
答案 1 :(得分:5)
可以吗?大概。 它应该完成吗?可能不是,否则这将是铁轨的一部分,或者已经有一个伟大的宝石。
如果您有特殊的复杂控制器操作正在执行大量的db活动,并且您希望它们处于事务中,我的建议是将此业务逻辑和持久性转换为模型方法,并将您的事务放在那里。这也使您可以更好地控制您可能并不总是希望这种情况发生的情况。
如果你真的,真的想要这样做,我敢打赌你可以用Rack中间件来做,就像这个(未经测试的)https://gist.github.com/1477287:
# make this class in lib/transactional_requests.rb, and load it on start
require 'activerecord'
class TransactionalRequests
def initialize(app)
@app = app
end
def call(env)
ActiveRecord::Base.transaction do
@app.call(env)
end
end
end
# and in the app config
config.middleware.use "TransactionalRequest"