简体   繁体   中英

What is the best way to lock records for processing in Rails?

It's easy with simple transactions, however with complex work thats not that clear.

Let's assume we have models with some relations, for example lets take User and Account , in Controller we validate that User has enough balance and his Account is also valid. On that step we can query record with pessimistic locking, however it wouldn't help, because we release lock as soon as we receive data.

Those validations took some time and then we actually start doing work, querying remote API's and do complex computations, whatever.. While everything is in process we still need to hold lock on both User and Account models.

And here goes the question, what is the best way to lock records, should one add mutex in Controller to cover validation and work? Or do another validation in open transaction when models fetched again with pessimistic locking? Or maybe theres another way I missed?

Pseudo Code

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

You can use ActiveRecord transactions if I get your question right:

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

If there are long delays, I would say to use an optimistic lock. If there are no delays, then a pessimistic lock is better.

If you need to update information in a remote API with some data you validated locally, I would say to use a pessimistic lock.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM