在放下几年后,我正在尝试重新学习 NodeJS,因此我正在构建一个小型银行网站作为测试。我决定将 Sequelize 用于我的 ORM,但我在以我喜欢的方式在人与人之间汇款时遇到了一些麻烦。 这是我的第一次尝试:
// 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);
});
这是有效的,因为钱仍然在人与人之间转移,但它仍然没有验证模型。我认为原因是 .validate()
和 .reload()
方法没有添加 transaction: t
的能力上的参数。
我的问题是是否有一种方法可以在交易中进行验证,但我也希望得到一些帮助来解决这个“回调 hell ”。同样,我已经有一段时间没有使用 JS 了,所以我现在才知道可能有更好的方法来做这件事。
谢谢!
最佳答案
我相信您无法在 Model
的 increment
和 decrement
上触发验证,并且需要有实例。在某些 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;
}
}
关于javascript - 如何验证 Sequelize 交易并使其看起来不错,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44826730/