gpt4 book ai didi

ruby-on-rails - 如何判断 ActiveRecord::Base.transaction block 何时提交?

转载 作者:行者123 更新时间:2023-12-04 06:00:23 25 4
gpt4 key购买 nike

common problem使用后台作业和 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

在这种情况下,据我所知,您实际上无法访问方便的 after_commit打回来。

我想在上面的例子中,你可以有 ThingModel将作业排入其 after_commit回调,但随后您正在传播 SomeServiceObject 应该承担的责任跨不同的类(class),这感觉不对。

鉴于以上所有情况,是否有任何合理的方法可以知道何时 ActiveRecord::Base.transaction阻止提交,而无需求助于任何特定模型的 after_commit打回来?

谢谢! :-D

(另见: How to force Rails ActiveRecord to commit a transaction flush)

最佳答案

它比你想象的要简单。后 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

关于ruby-on-rails - 如何判断 ActiveRecord::Base.transaction block 何时提交?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39022907/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com