Verhindern von datenbankbezogenen Racebedingungen in Node.js
Ich versuche zu verstehen, wie bei Verwendung von Node.js die aynchrone Sicherheit bei Verwendung einer Instanz eines Modells gewährleistet werden kann. Hier verwende ich den Mongoose-ODM in Codebeispielen, aber die Frage gilt für alle Fälle, in denen eine Datenbank mit dem von Node.js verwendeten asynchronen ereignisgesteuerten E / A-Ansatz verwendet wird.
Betrachten Sie den folgenden Code (der Mongoose für MongoDB-Abfragen verwendet):
Snippet AMyModel.findOne( { _id : <id #1> }, function( err, doc ) {
MyOtherModel.findOne( { _id : someOtherId }, ( function(err, otherDoc ) {
if (doc.field1 === otherDoc.otherField) {
doc.field2 = 0; // assign some new value to a field on the model
}
doc.save( function() { console.log( 'success' ); }
});
});
In einem separaten Teil der Anwendung könnte das von MyModel beschriebene Dokument aktualisiert werden. Betrachten Sie den folgenden Code:
Snippet BMyModel.update( { _id : <id #1> }, { $set : { field1 : someValue }, callback );
In Snippet A wird eine MongoDB-Abfrage mit einem registrierten Rückruf ausgegeben, der ausgelöst wird, sobald das Dokument fertig ist. Eine von MyModel beschriebene Instanz des Dokuments bleibt im Speicher (im Objekt "doc") erhalten. Die folgende Sequenz kann auftreten:
Snippet A ausführtFür MyModel wird eine Abfrage initiiert, die einen Rückruf (Rückruf A) für die spätere Verwendung registriert<< Die Node-Ereignisschleife wird ausgeführt >>MyModel wird aus der Datenbank abgerufen und der registrierte Rückruf ausgeführt (Rückruf A)Für MyOtherModel wird eine Abfrage initiiert, die einen Rückruf zur späteren Verwendung registriert (Rückruf B).<< Die Node-Ereignisschleife wird ausgeführt >>Snippet B ausführtDas Dokument (ID # 1) wird aktualisiert<< Die Node-Ereignisschleife wird ausgeführt >>MyOtherModel wird aus der Datenbank abgerufen und führt den registrierten Rückruf aus (Rückruf B).Die veraltete Version des Dokuments (ID # 1) wird in einem Vergleich falsch verwendet.FragenGibt es in Node.js / MongoDB Garantien dafür, dass diese Art von Racebedingung nicht eintritt?Was kann ich tun, um dieses Szenario deterministisch zu verhindern?Während Node Code auf Singlethread-Weise ausführt, scheint es mir, dass jede Erlaubnis zur Ausführung der Ereignisschleife die Tür für möglicherweise veraltete Daten öffnet. Bitte korrigieren Sie mich, wenn diese Beobachtung falsch ist.