2017-06-29 67 views
1

我想重新學習NodeJS幾年後放下來,所以我建立一個小銀行網站作爲測試。我決定使用Sequelize作爲我的ORM,但我在用我喜歡的方式在人們之間傳送資金時遇到了一些麻煩。 這是我第一次嘗試:如何驗證Sequelize交易,並使其看起來不錯

// myUsername - who to take the money from 
// sendUsername - who to send the money to 
// money - amount of money to be sent from `myUsername`->`sendUsername` 
// Transaction is created to keep a log of banking transactions for record-keeping. 
module.exports = (myUsername, sendUsername, money, done) => { 
    // Create transaction so that errors will roll back 
    connection.transaction(t => { 
     return Promise.all([ 
      User.increment('balance', { 
       by: money, 
       where: { username: myUsername }, 
       transaction: t 
      }), 
      User.increment('balance', { 
       by: -money, 
       where: { username: sendUsername }, 
       transaction: t 
      }), 
      Transaction.create({ 
       fromUser: myUsername, 
       toUser: sendUsername, 
       value: money 
      }, { transaction: t }) 
     ]); 
    }).then(result => { 
     return done(null); 
    }).catch(err => { 
     return done(err); 
    }); 
}; 

這個工作,但是當它被遞增它並沒有驗證模型。我希望事務在模型不驗證時失敗。我的下一個嘗試是去回調,如下所示(相同的函數頭):

connection.transaction(t => { 
     // Find the user to take money from 
     return User 
     .findOne({ where: { username: myUsername } }, { transaction: t })    .then(myUser => { 
        // Decrement money 
        return myUser 
        .decrement('balance', { by: money, transaction: t }) 
        .then(myUser => { 
          // Reload model to validate data 
          return myUser.reload(myUser => { 
            // Validate modified model 
            return myUser.validate(() => { 
              // Find user to give money to 
              return User 
              .findOne({ where: { username: sendUsername } }, { transaction: t }) 
              .then(sendUser => { 
                // Increment balance 
                return sendUser 
                .increment('balance', { by: money, transaction: t }) 
                .then(sendUser => { 
                  // Reload model 
                  return sendUser.reload(sendUser => { 
                    // Validate model 
                    return sendUser.validate(() => { 
                      // Create a transaction for record-keeping 
                      return Transaction 
                      .create({ 
                        fromUser: myUser.id, 
                        toUser: sendUser.id, 
                        value: money 
                      }, { transaction: t }); 
                    }); 
                  }); 
                }); 
              }); 
            }); 
          }); 
        }); 
      }); 
    }).then(result => { 
      return done(null); 
    }).catch(err => { 
      return done(err); 
    }); 

這工作,因爲錢還是轉移beetween人,但它仍然沒有驗證模式。我認爲原因是.validate().reload()方法不能在其上添加transaction: t參數。 我的問題是,如果有一種方法可以在事務中進行驗證,但是我還想要一些幫助修復這個「回調地獄」。再一次,我還沒有完成JS,所以現在可能有更好的方法來實現這一點,現在我剛剛意識到了這一點。

謝謝!

回答

1

我相信你不能得到驗證在Modelincrementdecrement上觸發,並且需要有實例。在一些sequelize模型方法,您可以配置驗證運行,但它不look like it here

我會做這樣的

module.exports = async function(myUserId, sendUserId, money) { 
    const transaction = await connection.transaction(); 
    try { 
    const [myUser, sendUser] = await Promise.all([ 
     User.findById(myUserId, { transaction }), 
     User.findById(sendUserId, { transaction }) 
    ]); 
    await Promise.all([ 
     myUser.increment('balance', { 
     by: money, 
     transaction 
     }), 
     myUser.increment('balance', { 
     by: -money, 
     transaction 
     }) 
    ]); 
    await Transaction.create({...}, { transaction }) 
    await transaction.commit(); 
    } catch(e) { 
    await transaction.rollback(); 
    throw e; 
    } 
} 
相關問題