查找,如果不存在,插入,漏洞

Find, if not exists, insert, vulenrability

至少同时执行 >10 个请求,此代码插入 4 个相同的记录,但必须只插入 1 个。

用户只能启动 1 个活动游戏。 (在活跃的游戏领域finished = false

console.log('performing request');
const activeGame = await db.Game.findOne({ uid, finished: false });
if (activeGame !== null) {
    console.log('errored');
    return { error: 'Finish previous game.' };
} else {
    console.log('inserted');
    const game = new db.Game({
        uid,
        moves: new Array(5*5).fill(0)
    });
    game.save();
    return game;
}

同时记录 10 个请求:

performing request
inserted
performing request
performing request
inserted
performing request
inserted
inserted
performing request
errored
performing request
errored
performing request
errored
performing request
errored
performing request
performing request
errored
errored

交易对我没有帮助。

当然,这段代码很容易出现竞争条件。为避免这种情况,您可以使用 All you need is a partial unique index。将其应用于文档的 uid 字段,其中 finished: false 等等,您现在不能为同一用户插入两个活动游戏。

你的 uid 不同所以它会插入这些时间。如果您将传递相同的 uid,那么它会根据您的要求工作。

你可以试试这些。并阅读 save() 功能。

console.log('performing request');
const activeGame = await db.Game.findOne({ _id: uid, finished: false });
if (activeGame == null) {
      console.log('inserted');
    const game = new db.Game({
        moves: new Array(5*5).fill(0)
    });
    game.save();
    return game;
} else {
    console.log('errored');
    return { error: 'Finish previous game.' };
}

console.log('performing request');
const activeGame = await db.Game.findOne({ _id: uid, finished: false });
activeGame.save()