Igor Kasuan
Igor Kasuan

Reputation: 842

node js. Sequelize transactions

I have 'Banks' table with 'money' field in my database,

Users can withdraw money periodically, but they can withdraw only if there is money > 0 in the bank.

Firstly I should get the entity of bank, then check if(bank.money > amountToWithdraw) and then withdraw this amount.

Imagine the situation, when concurrent user try to withdraw some money. In that moment when I check if(bank.money > amountToWithdraw) other user can perform withdraw operation and the real bank.money amount in the DB will be less.

How to apply transaction to finding bank operation(how to lock bank entity)?

models.sequelize.transaction(function (t) {

return models.Banks.findOne({where: {
    money: {
      $gt: 0
    }
  }).then(function(bank){

    //in this moment other user finished the same operation
// how to lock access for editing bank object by other users after //findOne method?

    bank.money -= amountToWithdraw;
    return bank.save({transaction: t});
  })
})

Upvotes: 17

Views: 22048

Answers (1)

Ivan Drinchev
Ivan Drinchev

Reputation: 19581

You can use a lock on the row of the bank.

It can look something like this, depending on your database.

models.sequelize.transaction(function (t) {

return models.Banks.findOne({where: {
       money: {
         $gt: 0
       }
    }, lock: t.LOCK.UPDATE, transaction: t }).then(function(bank){

    bank.money -= amountToWithdraw;
    return bank.save({transaction: t});
  })
})

Upvotes: 44

Related Questions