我在服务对象中有一个方法,它组成应该包含在事务中的操作。其中一些操作也包含在事务中。例如:
class PostCreator
def create
ActiveRecord::Base.transaction do
post.do_this
post.do_that
user.do_more(post, other_stuff)
end
end
end
def Post
def do_this
transaction do; ...; end
end
end
我需要任何嵌套的失败,一直到顶部,但我不知道如何实现这一点,nested transactions上的ActiveRecord文档似乎没有提供解决方案。来自文档:
# Standard nesting
User.transaction do
User.create(username: 'Kotori')
User.transaction do
User.create(username: 'Nemu')
raise ActiveRecord::Rollback # This won't bubble up:
# _Both_ users will still be created.
end
end
# Nesting with `requires_new: true` on the nested transaction
User.transaction do
User.create(username: 'Kotori')
User.transaction(requires_new: true) do
User.create(username: 'Nemu')
raise ActiveRecord::Rollback # This won't bubble up either
# "Kotori" will still be created.
end
end
答案 0 :(得分:28)
以下是您在嵌套交易中出现失败的方法:
User.transaction do
User.create(username: 'Kotori')
raise ActiveRecord::Rollback unless User.transaction(requires_new: true) do
User.create(username: 'Nemu')
raise ActiveRecord::Rollback
end
end
基本上,您必须在顶级事务中引发错误,以便进行回滚。为此,如果嵌套事务返回falsey值(nil)或truthy值,则引发错误。
希望有所帮助!
答案 1 :(得分:12)
另一种更简单的方法,你可以引发一个CustomError< StandardError的。与ActiveRecord :: Rollback不同,Error将通过父事务冒泡。您可以在任何需要的地方处理它。所有其他内部交易将被回滚。
尝试以下模板。
ActiveRecord::Base.transacton do
ActiveRecord::Base.transacton do
raise StandardError.new
end
end
答案 2 :(得分:0)
在嵌套事务的情况下,抛出自定义错误始终是一个不错的选择。请在nested-transations-in-rails上找到更多详细信息。