ActiveRecord::Base.transaction do
do_this
Something.after_commit.action
do_that
end
# Something.action is fired/run in case no exceptions in transaction
如何实现这一目标?
注意:我们没有看到交易的开始和结束位置(我的意思是transaction do
和end
)
答案 0 :(得分:-1)
您必须使用此模式,save!
(出错时会引发异常):
begin
do_this_before_update_the_db
ActiveRecord::Base.transaction do
update_1_db_if_no_fails
update_2_db_if_no_fails
...
update_n_db_if_no_fails
end
DO-THIS-AFTER-COMMIT-ONLY-IF-NO-EXCEPTIONS
rescue Exception => exception
do_this_if_some_update_fails # depending on the exception you must raise again from here.
ensure
do_this_always_fail_or_no # this runs after commit
end
您不能将after_commit
放在事务中,因为这在事务内部运行之前就已经完成了。
事务块内的所有内容都在块的末尾运行一次提交。所有回调都在此事务中运行。并且所有缩进的事务都在此事务中运行(只有一个提交)。您可以找到详细信息here。
您必须在日志中看到,最后只有一个提交。
此外,您可以在update_2_db_if_no_fails
上使用此模式,并且运行的确保块始终失败或没有update_2。这在第一个事务中运行,但与您的模型after_commit回调不同。
答案 1 :(得分:-1)
据我了解你的问题,你想要定义应该在转换中的事务之后运行的代码吗?但是你不想马上运行它?
如果是这种情况,可以使用proc
来实现。有关procs的信息。
所以代码就像:
no_exceptions = true
ActiveRecord::Base.transaction do
do_this
after_code = Proc.new do |no_e|
# Code defining how to act no_e gives you info if exceptions where fired.
end
do_that
rescue Exception => e
no_exceptions = false
end
after_code.call(no_exceptions)
我希望这就是你在寻找的地方。