事务提交后触发方法

时间:2015-03-18 02:07:22

标签: ruby-on-rails ruby activerecord transactions

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 doend

2 个答案:

答案 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)

我希望这就是你在寻找的地方。