2017-07-24 5 views
0

Ich habe Code geschrieben, um Credits von einem Benutzer auf einen anderen zu übertragen, ich habe MongoDB als Datenbank ausgewählt. Aber mir wurde gesagt, dass ich Probleme mit der Datenbank in der Funktion transferCredits habe. Ich habe gesucht, konnte aber kein Problem finden.Suche nach Datenbankproblemen

function transferCredits(from, to, amt) { 
    var fromAccount = db.game_accounts.findOne({"name": from},{"credits": 1}); 
    var toAccount = db.game_accounts.findOne({"name": to},{"credits": 1}); 
    if (fromAccount.credits < amt) { 
    throw new BalanceError("not enough balance to transfer credits"); 
    } 
    db.game_accounts.update({name: from}, {$set: {credits: fromAccount.credits - amt}}); 
    db.game_accounts.update({name: to}, {$set: {credits: toAccount.credits + amt}}); 
} 

db.game_accounts.insert({name: "John", credits: 1000}); 
db.game_accounts.insert({name: "Jane", credits: 1000}); 

// John transfers credits to Jane 
transferCredits("John", "Jane", 100); 
+0

Wer hat Ihnen gesagt, dass könnte spezifischer gewesen sein und einfach gesagt, "Transaktionen" sind in der Regel erforderlich, um die Konsistenz zwischen mehreren Schreiboperationen zu gewährleisten. Ihre spezifische Sprache ist jedoch typisch für die Art von vorurteilsbehaftetem Unsinn, der von den Böswilligen ausgestrahlt wird, die folgern, dass die "Datenbank" (MongoDB) einen solchen Prozess nicht durch mangelnde Unterstützung für Transaktionen bewältigen kann. Ihre "Implementierung" hat dies nicht bestanden, aber es ist sehr gut möglich, mit einer anderen Modellierung eine solche "Soll/Haben" -Ausgleichstransaktion mit MongoDB durchzuführen. Du machst es einfach anders. –

Antwort

0

Sie sagen uns nicht, was das Problem ist, so können wir nur spekulieren ...

Was ich sehe, ist, dass dieser Teil falsch sein könnte: weil

db.game_accounts.update({name: from}, {$set: {credits: fromAccount.credits - amt}}); 
db.game_accounts.update({name: to}, {$set: {credits: toAccount.credits + amt}}); 

Dies ist

Es könnte eine weitere Transaktion zwischen dem findOne() und dem update() stattfinden. Sie verwenden besser $inc, die den gleichen Vorgang ausführen wird, ohne sich jedoch den Rennbedingungen zu öffnen.

Beachten Sie, dass Subtraktion I einfach mit -1 multipliziert, um die Zahl negativ zu machen.

Wenn der Benutzer versucht, einem anderen Benutzer -10 Guthaben zu geben, kann er stattdessen 10 Guthaben STEHLEN ... Mehrere andere Überprüfungen müssen so durchgeführt werden, um eine gültige Transaktion zu gewährleisten.

Nebenbei gesagt, MongoDB ist nicht wirklich für diese Art von Transaktion gedacht, bevorzugen Sie vielleicht eine andere Art von DB, die sicherstellen kann, dass die Daten auf dem neuesten Stand sind und alle Operationen verfolgt und erledigt werden.

+0

Was ist zu spekulieren? Wenn Sie dieses sehr gängige Muster des Finanzsystems wirklich verstanden haben, bedeutet das im Grunde genommen, dass Sie ein "Paar" von Einträgen benötigen, die denselben Betrag "abbuchen" und "gutschreiben", sowohl von einem Konto als auch in ein anderes. Wie bereits erwähnt, bedeutet das "datenbankbezogene Problem" in MongoDB "Transaktionen" oder "Fehlen". Wenn Sie also "zwei Schreibvorgänge" haben (was sowohl die Frage des OP als auch Ihre Antwort betrifft), was passiert, wenn einer dieser Fehler auftritt? Wenn Sie eine Antwort einreichen, müssen Sie die Frage zuerst verstehen. –

+0

I Ich habe meine Antwort so bearbeitet, dass sie eine etwas naive Art enthält, die Transaktion entsprechend zu handhaben, aber ich sage immer wieder, dass es reine Spekulation ist, dass die Frage genau diese Frage betrifft ... Da gibt es viele andere mögliche Probleme in dem gegebenen Code-Snippet. – Salketer

+0

Aus meiner Lektüre, ich glaube nicht, dass Sie es sehr gut verstehen. Die "MongoDB Weg", um dies zu implementieren würde nur "eine Schreiboperation". –