Ich versuche, eine wirklich einfache Shopping-App zu bauen, wo Benutzer Artikel mit virtueller Währung kaufen können.Sperren in Mongo und Nodejs
Ich benutze mehrere NodeJS-Prozesse dafür, also habe ich Angst vor dem asynchronen Teil der Dinge. Diese
ist, was ich tue:
app.post('/buy', function(req, res){
User.findOne({_id: req.userId}, function(err, user){
if(user.balance >= ITEM_PRICE){
User.decrementBalance({_id: req.userId}, function(err){
//Do transaction, give item to user, etc
});
} else {
//Not enough money
}
});
});
Das Problem bei diesem Ansatz ist, dass Benutzer mehr/kaufen Anforderungen in einem sehr kurzen Zeitrahmen einreichen können. Dies könnte zu einer Wettlaufsituation führen, bei der die zweite Anfrage das Kontostand des Benutzers überprüft hat, bevor der erste es dekrementieren kann. Dies führt dazu, dass der Benutzer einen negativen Wert hat und viel mehr Gegenstände herausnimmt, als ihm sein Gleichgewicht erlaubte.
Gibt es eine Möglichkeit, dies zu lösen? Ich denke daran, ein User.update() zu machen und zu überprüfen, ob der Benutzer geändert wurde oder nicht. Könnte das funktionieren?
So verarbeitet Mongo Lese-/Schreibvorgänge einzeln? – StevenDaGee
@StevenDaGee Ich aktualisierte meine Antwort mit einigen weiteren Informationen. – robertklep