我一直在编写代码将信用从一个用户转移到另一个用户,我已经选择了MongoDB作为数据库。但是我告诉我在transferCredits函数中有数据库相关的问题。我一直在寻找,但无法找到任何问题。
function transferCredits(from, to, amt) {
var fromAccount = db.game_accounts.findOne({"name": from},{"credits": 1});
var toAccount = db.game_accounts.findOne({"name": to},{"credits": 1});
if (fromAccount.credits < amt) {
throw new BalanceError("not enough balance to transfer credits");
}
db.game_accounts.update({name: from}, {$set: {credits: fromAccount.credits - amt}});
db.game_accounts.update({name: to}, {$set: {credits: toAccount.credits + amt}});
}
db.game_accounts.insert({name: "John", credits: 1000});
db.game_accounts.insert({name: "Jane", credits: 1000});
// John transfers credits to Jane
transferCredits("John", "Jane", 100);
答案 0 :(得分:0)
你没有告诉我们问题是什么,所以我们只能推测......
我看到的是这部分可能是错误的:
db.game_accounts.update({name: from}, {$set: {credits: fromAccount.credits - amt}});
db.game_accounts.update({name: to}, {$set: {credits: toAccount.credits + amt}});
这是因为findOne()
和update()
之间可能会发生另一笔交易。你最好使用$inc
来执行相同的操作,但不要让自己适应竞争条件。
db.game_accounts.update({name: from}, {$inc: {credits: amt*-1}},function(err,res){
if (err) throw err;
db.game_accounts.update({name: to}, {$inc: {credits: amt}}, function(err,res){
if (err) throw err;
db.game_accounts.update({name: from}, {$inc: {credits: amt}});
});
});
请注意,要减去我,只需乘以-1即可将数字设为负数。
除此之外,如果用户试图给另一个用户提供-10个学分,他将能够转换10个学分而不是......需要进行多个其他检查以确保有效的交易。
另一方面,MongoDB并不适用于此类交易,您可能更喜欢使用其他类型的数据库,以确保数据是最新的,并且所有操作都会被跟踪和完成。