Meine Server-Anwendung (mit node.js, mongodb, mongoose) verfügt über eine Sammlung von Dokumenten, für die es wichtig ist, dass zwei Clientanwendungen sie nicht gleichzeitig ändern können, ohne sich gegenseitig zu ändern.Verhindern des gleichzeitigen Zugriffs auf Dokumente in Mongoose
Um dies zu verhindern, habe ich ein einfaches Dokument Versionierungssystem hinzugefügt: ein Pre-Hook auf das Schema, das überprüft, ob die Version des Dokuments gültig ist (d. H. Nicht höher als die, die der Client zuletzt gelesen). Auf den ersten Blick wirkt es fein:
// 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()
}
})
})
Das Problem ist folgendes:
Wenn ein Benutzer Dokument zur gleichen Zeit von zwei Client-Anwendungen gespeichert wird, ist es möglich, dass diese Verschachtelung zwischen dem Pre-Haken und die tatsächlichen Sicherungsoperationen? Was ich meine, ist die folgende, sich vorstellen Zeit von links nach rechts und v die Versionsnummer (die von save beibehalten wird):
App1: findById(pre)[v:1] save[v->2]
App2: findById(pre)[v:1] save[v->2]
Resultierende in App1 etwas speichern, die inzwischen geändert wurde (von App2), und es hat keine Möglichkeit zu bemerken, dass es modifiziert wurde. App2's Update ist komplett verloren.
Meine Frage könnte dazu führen, dass: Kann der Mongoose-Pre-Hook und die Speichermethode in einem Atomschritt passieren?
Wenn nicht, könnten Sie mir einen Vorschlag geben, wie Sie dieses Problem beheben können, damit kein Update verloren geht?
Vielen Dank!
Danke, das funktioniert. Insbesondere das von Ihnen vorgeschlagene Muster, da es die Überprüfung der Dokumentversion vor dem Update-Versuch ermöglicht. – Zxifer