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
def bet
bet = Bet.new bet_params
if bet.valid?
BetService.make_bet(bet) #do actual work, and
end
end
class Bet
# some code
validate :balance # self.user.lock!.balance > X
end
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.