Ruby on rails 使用ActiveRecord确保方法内的事务

Ruby on rails 使用ActiveRecord确保方法内的事务,ruby-on-rails,transactions,rails-activerecord,Ruby On Rails,Transactions,Rails Activerecord,在这种情况下,我希望一个方法在事务中工作,但前提是事务尚未启动。这里有一个人为的例子来提炼我所说的: class ConductBusinessLogic def initialize(params) @params = params end def process! ActiveRecord::Base.transaction do ModelA.create_multiple(params[:model_a]) ModelB.create

在这种情况下,我希望一个方法在事务中工作,但前提是事务尚未启动。这里有一个人为的例子来提炼我所说的:

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
class-ConductBusinessLogic
def初始化(参数)
@params=params
结束
def程序!
ActiveRecord::Base.transaction do
ModelA.create_multiple(参数[:model_a])
ModelB.创建多个(参数[:model\u a])
结束
结束
结束
类ModelA
基本上,我不希望这些作为嵌套事务。我希望
.create\u multiple
方法仅在事务中尚未调用时才启动事务,例如通过
ConductBusinessLogic\process。如果模型方法是自己调用的,它们应该启动自己的事务,但是如果它们已经在事务内部被调用,比如通过
ConductBusinessLogic#process,它们不应嵌套子事务

我不知道Rails提供这种开箱即用的方式。如果我按原样运行上面的代码,并且其中一个模型方法触发了回滚,那么整个事务仍将进行,因为子事务吞没了
ActiveRecord::rollback
异常。如果在子事务上使用
requires\u new
选项,则保存点将用于模拟嵌套事务,并且只有该子事务将实际回滚。我想要的行为是类似于
ActiveRecord::Base的效果。确保\u事务
,这样,只有在还没有外部事务时才启动新事务,这样任何子事务都可以触发整个外部事务的回滚。这将允许这些方法本身是事务性的,但如果有父事务,则遵从父事务


是否有一种内置的方法来实现这种行为,如果没有,是否有一个gem或补丁可以工作?

只需向
ModelA
ModelB
类添加一个
create\u multiple\u而不使用事务
方法如何?看起来是这样的:

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
class-ConductBusinessLogic
def初始化(参数)
@params=params
结束
def程序!
ActiveRecord::Base.transaction do
ModelA.创建不带事务的多个(params[:model\u a])
ModelB.创建不带事务的多个(params[:model_a])
结束
结束
结束
类ModelA
然后您的常规
create\u multiple
将像以前一样工作,但是如果您不需要事务,您只需调用
create\u multiple\u而不需要事务

怎么样?