randomguy
randomguy

Reputation: 12242

How to prevent concurrent requests from sneaking by a check in Rails?

User has a balance of 1.

Two concurrent requests to make a transfer worth of 1 come in the following manner:

Transfer A passes validations as the user has enough balance
Transfer B passes validations as the user has enough balance
Transfer A is made
Transfer B is made

In a result, the user is left with a -1 balance, which obviously shouldn't happen.

How is this prevented?

Upvotes: 1

Views: 207

Answers (1)

CDub
CDub

Reputation: 13344

You could use with_lock around the transaction. This is just an example, assuming you have logic around an account:

account = user.account

account.with_lock do
  break unless account.balance.sufficient?

  account.transfer(amount)

  account.save!
end

Check out the pessimistic locking documentation.

Upvotes: 2

Related Questions