2016-05-17 7 views
2

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!

Antwort

2

MongoDB hat findAndModify, die für ein einzelnes übereinstimmendes Dokument eine atomare Operation ist.

Mongoose hat verschiedene Methoden, die diese Methode verwenden, und ich denke, dass sie Ihren Anwendungsfall anzupassen:

Another Lösung (eine, die Mongoose uns selbst es ist auch für seine own document versioning), die Update Document if Current Muster zu verwenden.

+0

Danke, das funktioniert. Insbesondere das von Ihnen vorgeschlagene Muster, da es die Überprüfung der Dokumentversion vor dem Update-Versuch ermöglicht. – Zxifer

Verwandte Themen