简单的交易很容易,但是复杂的工作还不清楚。

假设我们有一些具有某种关系的模型,例如让UserAccount,在Controller中,我们验证User具有足够的平衡,并且他的Account也有效。在这一步中,我们可以使用悲观锁定来查询记录,但这无济于事,因为我们一收到数据就立即释放锁定。

这些验证花费了一些时间,然后我们实际上开始工作,查询远程API并进行复杂的计算,无论如何。尽管一切都在进行中,我们仍然需要同时锁定用户模型和帐户模型。

接下来的问题是,锁定记录的最佳方法是什么,是否应该在Controller中添加互斥锁以覆盖验证和工作?还是在使用悲观锁定再次获取模型时在开放式交易中进行另一项验证?也许还有另一种我想念的方式?

伪代码

index_controller.rb

def bet
  bet = Bet.new bet_params

  if bet.valid?
    BetService.make_bet(bet) #do actual work, and
  end
end


bet.rb

class Bet
  # some code
  validate :balance # self.user.lock!.balance > X
end


bet_service.rb

class BetService
  def self.make_bet(bet)
    #some long work
    ActiveRecord::Base.transaction do
       bet.user.lock!.balance -= X
    end
  end
end

最佳答案

如果我的问题正确,则可以使用ActiveRecord事务:

ActiveRecord::Base.transaction do
  # all queries in here are in a single SQL transaction
end

10-08 04:24