在MongoDB中随机编辑随机数

我正在使用Expressjs,Socket.io和Mongoose进行多人游戏。 玩家join游戏,并在有足够的玩家玩时开始。 我会在游戏开始的同时提醒游戏中的所有玩家,所以我正在遇到并发问题,以改变游戏状态来“玩”和初始化angular色。 有时候angular色会被分配两次,这会弄乱游戏。

我试图按照这里和这里推荐的方法添加一个随机数,但是我无法工作,而且我也不是很了解它。 MongoDB是否将其视为具有特殊属性的特殊值? 或者是现在取决于MongoDB的一些现有属性?

以下是游戏模型的相关部分:

GameSchema = mongoose.Schema nonce: type: mongoose.Schema.Types.ObjectId required: true default: mongoose.Types.ObjectId name: type: String required: true unique: true state: type: String enum: ["setup", "unstarted", "playing", "assassinating", "good_won", "bad_won", "discontinued"] default: "setup" required: true characters: [String] players: [{ type: mongoose.Schema.Types.ObjectId, ref: "Player" }] GameSchema.statics.findByIdAndStart = (id, done) -> Game = this Game.findById id, (err, game) -> return done err, game if err or game.state is "playing" changes = state: "playing" nonce: mongoose.Types.ObjectId() Game.update { id: id, nonce: game.nonce }, changes, (err) -> return done err if err Game.findById(id).populate("players").exec (err, game) -> return done err if err characterSelection = new CharacterSelection game.characters async.eachSeries game.players, ((player, next) -> player.character = characterSelection.assignCharacter() player.save next ), (err) -> done err, game 

如何防止同时编辑我的模型?

将模型的属性命名为“nonce”没有什么特别之处,它只是一个术语/约定,意思是“仅使用一次”,并且我们要求每次产生时都是唯一的。

你在MongoDB中定义了一个ObjectId作为一个ObjectId,这样每次生成它时你都应该得到一个唯一的值。

这个工作的关键是,当你调用update()时,你使用文档现有的nonce值,这样你的更新可以确保在你发出findById()和调用更新之间没有其他玩家或用户更新过文档方法。 如果更新成功,则您的文档将获取您在更改对象中放置的新生成的nonce值。

看看你的代码,我认为它看起来是正确的,除非你不处理的情况下,更新没有改变任何logging,只有错误的情况下。 更新的callback函数 ( 在Mongoose 3.8.x中 )带有第二个参数numberAffected,您可以使用它来确定是否有文档受到影响。

 Game.update { id: id, nonce: game.nonce }, changes, (err, numberAffected) -> return done err if err return done "Conflict!" if !numberAffected 

您需要决定如何处理冲突情况,在此示例中 ,代码在出错之前多次重试呼叫。