Ich weiß, dass es hier ähnliche Fragen gibt, aber sie fordern mich entweder auf, zu regulären RDBMS-Systemen zurückzukehren, wenn ich Transaktionen benötige oder atomare Operationen oder ein zweiphasiges Festschreiben verwende . Die zweite Lösung scheint die beste Wahl zu sein. Das dritte möchte ich nicht verfolgen, da anscheinend viele Dinge schief gehen könnten und ich es nicht in jeder Hinsicht testen kann. Es fällt mir schwer, mein Projekt für atomare Operationen umzugestalten. Ich weiß nicht, ob dies aus meiner eingeschränkten Sicht geschieht (ich habe bisher nur mit SQL-Datenbanken gearbeitet) oder ob dies tatsächlich nicht möglich ist.
Wir möchten MongoDB in unserem Unternehmen pilotieren. Wir haben ein relativ einfaches Projekt ausgewählt - ein SMS-Gateway. Es ermöglicht unserer Software, SMS-Nachrichten an das Mobilfunknetz zu senden, und das Gateway erledigt die Drecksarbeit: Die Kommunikation mit den Anbietern erfolgt über verschiedene Kommunikationsprotokolle. Das Gateway verwaltet auch die Abrechnung der Nachrichten. Jeder Kunde, der sich für den Service bewirbt, muss ein Guthaben kaufen. Das System verringert automatisch das Guthaben des Benutzers, wenn eine Nachricht gesendet wird, und verweigert den Zugriff, wenn das Guthaben nicht ausreicht. Auch weil wir Kunden von SMS-Anbietern von Drittanbietern sind, haben wir möglicherweise auch unsere eigenen Guthaben bei ihnen. Wir müssen auch diese im Auge behalten.
Ich begann darüber nachzudenken, wie ich die erforderlichen Daten mit MongoDB speichern kann, wenn ich die Komplexität reduziere (externe Abrechnung, SMS-Versand in der Warteschlange). Aus der SQL-Welt stammend, würde ich eine separate Tabelle für Benutzer erstellen, eine andere für SMS-Nachrichten und eine zum Speichern der Transaktionen in Bezug auf den Kontostand der Benutzer. Angenommen, ich erstelle separate Sammlungen für alle in MongoDB.
Stellen Sie sich eine SMS-Sendeaufgabe mit den folgenden Schritten in diesem vereinfachten System vor:
Überprüfen Sie, ob der Benutzer über ein ausreichendes Gleichgewicht verfügt. Zugriff verweigern, wenn nicht genügend Guthaben vorhanden ist
Senden und Speichern der Nachricht in der SMS-Sammlung mit den Details und Kosten (im Live-System hätte die Nachricht ein
status
Attribut und eine Aufgabe würde sie zur Zustellung abholen und den Preis der SMS entsprechend ihrem aktuellen Status festlegen).Verringern Sie das Guthaben der Benutzer um die Kosten der gesendeten Nachricht
Protokollieren Sie die Transaktion in der Transaktionssammlung
Was ist das Problem damit? MongoDB kann atomare Aktualisierungen nur für ein Dokument durchführen. Im vorherigen Ablauf kann es vorkommen, dass sich ein Fehler einschleicht und die Nachricht in der Datenbank gespeichert wird, der Kontostand des Benutzers jedoch nicht aktualisiert und / oder die Transaktion nicht protokolliert wird.
Ich hatte zwei Ideen:
Erstellen Sie eine einzelne Sammlung für die Benutzer und speichern Sie den Kontostand als Feld, benutzerbezogene Transaktionen und Nachrichten als Unterdokumente im Benutzerdokument. Da wir Dokumente atomar aktualisieren können, wird das Transaktionsproblem dadurch gelöst. Nachteile: Wenn der Benutzer viele SMS-Nachrichten sendet, kann das Dokument groß werden und das 4-MB-Dokumentlimit erreicht werden. Vielleicht kann ich in solchen Szenarien Verlaufsdokumente erstellen, aber ich denke nicht, dass dies eine gute Idee wäre. Ich weiß auch nicht, wie schnell das System wäre, wenn ich immer mehr Daten auf dasselbe große Dokument übertragen würde.
Erstellen Sie eine Sammlung für Benutzer und eine für Transaktionen. Es gibt zwei Arten von Transaktionen: Kreditkauf mit positiver Kontostandänderung und Nachrichten mit negativer Kontostandänderung. Die Transaktion kann ein Unterdokument haben. Beispielsweise können in gesendeten Nachrichten die Details der SMS in die Transaktion eingebettet werden. Nachteile: Ich speichere das aktuelle Benutzerguthaben nicht, daher muss ich es jedes Mal berechnen, wenn ein Benutzer versucht, eine Nachricht zu senden, um festzustellen, ob die Nachricht durchlaufen werden kann oder nicht. Ich befürchte, diese Berechnung kann langsam werden, wenn die Anzahl der gespeicherten Transaktionen zunimmt.
Ich bin ein bisschen verwirrt darüber, welche Methode ich wählen soll. Gibt es andere Lösungen? Ich konnte online keine Best Practices finden, um diese Art von Problemen zu umgehen. Ich denke, viele Programmierer, die versuchen, sich mit der NoSQL-Welt vertraut zu machen, stehen am Anfang vor ähnlichen Problemen.