Мое серверное приложение (используя node.js, mongodb, mongoose) имеет набор документов, для которых важно, чтобы два клиентских приложения не могли изменять их одновременно, не видя модификации друг друга.Предотвращение одновременного доступа к документам в 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 и метод сохранения на одном атомном шаге?
Если нет, не могли бы вы дать мне предложение о том, как исправить эту проблему, чтобы ни одно обновление не терялось?
Спасибо!
спасибо, что работает. Особенно шаблон, который вы предложили, поскольку он позволяет проверять версию документа перед попыткой обновления. – Zxifer