【发布时间】:2016-09-13 03:27:06
【问题描述】:
我的服务器应用程序(使用 node.js、mongodb、mongoose)有一个文档集合,重要的是两个客户端应用程序不能在没有看到彼此修改的情况下同时修改它们。
为了防止这种情况,我添加了一个简单的文档版本控制系统:架构上的预挂钩,用于检查文档的版本是否有效(即不高于客户端上次读取的版本)。乍一看,它工作正常:
// Validate version number
UserSchema.pre("save", function(next) {
var user = this
user.constructor.findById(user._id, function(err, userCurrent) { // userCurrent is the user that is currently in the db
if (err) return next(err)
if (userCurrent == null) return next()
if(userCurrent.docVersion > user.docVersion) {
return next(new Error("document was modified by someone else"))
} else {
user.docVersion = user.docVersion + 1
return next()
}
})
})
问题如下:
当两个客户端应用程序同时保存一个用户文档时,这些可能会在预挂钩和实际保存操作之间交错?我的意思如下,想象时间从左到右,v 是版本号(通过保存保留):
App1: findById(pre)[v:1] save[v->2]
App2: findById(pre)[v:1] save[v->2]
导致 App1 保存了同时(被 App2)修改过的东西,它没有办法注意到它被修改了。 App2 的更新完全丢失。
我的问题可能归结为:Mongoose pre-hook 和 save 方法是否发生在一个原子步骤中?
如果没有,您能否给我一个关于如何解决此问题的建议,以免更新丢失?
谢谢!
【问题讨论】: