Joh*_*lly 5 ruby-on-rails rails-activerecord
后台作业和 ActiveRecord 的一个常见问题是作业在所需模型提交到数据库之前排队并执行。
ActiveRecord 模型有一个很好的after_commit回调,可用于特定模型。
但是,假设您有一些涉及几个不同模型的业务逻辑,将这些逻辑塞进单个模型中是不合适的。因此,您编写某种服务/命令对象来执行事务块内的逻辑:
例如,类似于以下内容:
class SomeServiceObject
def execute
thing = create_thing_in_a_tx
# this notification often fires before the above transaction commits.
notify_user(thing)
end
private
def create_thing_in_a_tx
ActiveRecord::Base.transaction do
a = ModelA.new(foo: 'bar')
b = ModelB.new(a_record: a, biz: 'baz')
#... various other logic that doesn't really belong in a model ...
ThingModel.create!(b_record: b)
end
end
def notify_user(thing)
EnqueueJob.process_asyc(thing.id)
end
end
Run Code Online (Sandbox Code Playgroud)
在这种情况下,据我所知,您实际上无法访问方便的after_commit回调。
我想在上面的示例中,您可以ThingModel将作业排入其after_commit回调中,但是随后您将应承担的责任分散SomeServiceObject到不同的类中,这感觉不对。
鉴于上述所有内容,是否有任何合理的方法可以知道ActiveRecord::Base.transaction块何时提交,而无需求助于任何特定模型的after_commit回调?
谢谢!:-D
这比您想象的要简单。区块完成后ActiveRecord::Base.transaction,交易已被提交。
def create_thing_in_a_tx
begin
ActiveRecord::Base.transaction do
a = ModelA.new(foo: 'bar')
b = ModelB.new(a_record: a, biz: 'baz')
#... various other logic that doesn't really belong in a model ...
ThingModel.create!(b_record: b)
end
# The transaction COMMIT has happened. Do your after commit logic here.
rescue # any exception
# The transaction was aborted with a ROLLBACK.
# Your after commit logic above won't be executed.
end
end
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2555 次 |
| 最近记录: |