Chr*_*ent 5 transactions ruby-on-rails rails-activerecord
我有一种情况,我想在事务中使用一种方法,但只有在事务尚未启动的情况下.这是一个用来提炼我所说的内容的人为例子:
class ConductBusinessLogic
def initialize(params)
@params = params
end
def process!
ActiveRecord::Base.transaction do
ModelA.create_multiple(params[:model_a])
ModelB.create_multiple(params[:model_a])
end
end
end
class ModelA < ActiveRecord::Base
def self.create_multiple(params)
# I'd like the below to be more like "ensure_transaction"
ActiveRecord::Base.transaction do
params.each { |p| create(p) }
end
end
end
class ModelB < ActiveRecord::Base
def self.create_multiple(params)
# Again, a transaction here is only necessary if one has not already been started
ActiveRecord::Base.transaction do
params.each { |p| create(p) }
end
end
end
Run Code Online (Sandbox Code Playgroud)
基本上,我不希望这些作为嵌套事务.我希望这些.create_multiple方法只在事务中没有调用它们时启动事务,例如通过ConductBusinessLogic#process!.如果模型方法本身被调用,它们应该开始自己的事务,但如果它们已经在事务中被调用ConductBusinessLogic#process!,那么它们不应该嵌套子事务.
我不知道Rails提供开箱即用的方式.如果我按原样运行上面的代码并且其中一个模型方法触发了回滚,那么整个事务仍然会通过,因为子事务会吞下ActiveRecord::Rollback异常.如果我requires_new在子事务上使用该选项,则将使用保存点来模拟嵌套事务,并且实际只会回滚该子事务.我想要的行为是有效的ActiveRecord::Base.ensure_transaction,这样只有在没有外部事务时才启动新事务,这样任何子事务都可以触发整个外部事务的回滚.这将允许这些方法本身是事务性的,但如果有父事务,则遵从父事务.
有没有内置的方法来实现这种行为,如果没有,是否有一个宝石或补丁可以工作?
只在你的类create_multiple_without_transaction中添加一个方法怎么样?看起来像这样:ModelAModelB
class ConductBusinessLogic
def initialize(params)
@params = params
end
def process!
ActiveRecord::Base.transaction do
ModelA.create_multiple_without_transaction(params[:model_a])
ModelB.create_multiple_without_transaction(params[:model_a])
end
end
end
class ModelA < ActiveRecord::Base
def self.create_multiple(params)
# I'd like the below to be more like "ensure_transaction"
ActiveRecord::Base.transaction do
self.create_multiple_without_transaction(params)
end
end
def self.create_multiple_without_transaction(params)
params.each { |p| create(p) }
end
end
Run Code Online (Sandbox Code Playgroud)
那么您的常规操作create_multiple将像以前一样工作,但如果您不需要交易,您只需调用create_multiple_without_transaction