2015-05-13 8 views
7

Ich habe folgende Konfiguration:Django save() Verhalten mit autocommit Transaktionen

  • Mehrere Datenverarbeitung Arbeiter Konfiguration von django Ansicht get_conf() von http bekommen.
  • Konfiguration wird in django Modell mit MySQL/InnoDB Backend
  • Konfigurationsmodell gespeichert hat save() Methode überschrieben, die Arbeiter Konfiguration

ich bemerkt habe nachladen erzählt, dass manchmal die Arbeiter nicht korrekt angeben, die geänderte Konfiguration erhalten. Insbesondere, wenn die Zeit für das erneute Laden der Konfigu- ration kürzer als gewöhnlich war, erhielten die Worker eine "alte" Konfiguration von get_conf() (die letzte Änderung fehlte). Das in Django verwendete Transaktionsmodell ist der Standard-Autocommit.

Ich habe mit dem folgenden möglichen Szenario kommen, die das Verhalten verursachen könnte:

  1. Neue Konfiguration gespeichert wird
  2. save() kehrt aber MySQL/InnoDB noch verarbeitet die (Auto) verpflichten
  3. Arbeiter gebootet und hTTP-Anforderung für neue Konfiguration
  4. MySQL (auto) begehen Oberflächen
machen 0

Ist der Schritt 2 im obigen Szenario möglich? Das heißt, kann django Modell save() zurückgeben, bevor die Daten tatsächlich in der DB festgeschrieben werden, wenn die Autocommit-Transaktionsmethode verwendet wird? Oder, um eine Ebene nach unten zu gehen, kann MySQL Autocommitting INSERT oder UPDATE Operation beenden, bevor das Commit abgeschlossen ist (Update/Einfügen sichtbar für andere Transaktionen)?

+0

Verwenden Sie InnoDB oder MyISAM für Ihre Engine? – FlipperPA

+0

InnoDB. Die Datenbank läuft auf Amazon RDS mit Standardkonfiguration.Es gibt einige große Tabellen, aber die Tabelle (n) im Zusammenhang mit diesem Problem sind klein (in der Größenordnung von 128 kb oder so) – jhonkola

+0

Können Sie Autocommit nur für diesen Fall ausschalten? – sobolevn

Antwort

0

Das sieht auf jeden Fall wie ein Race-Bedingung.

Das von Ihnen beschriebene Szenario sollte niemals vorkommen, wenn nur ein Skript und eine Datenbank vorhanden sind. Wenn Sie speichern(), kehrt die Methode erst zurück, wenn die Daten tatsächlich an die Datenbank übergeben wurden.

Wenn Sie jedoch eine Master/Slave-Konfiguration verwenden, könnten Sie Opfer der Replikationsverzögerung werden: Wenn Sie auf den Master schreiben, aber die Slaves lesen, ist es durchaus möglich, dass Ihr Skript nicht wartet lang genug für die Replikation, und Sie haben das alte conf vom Slave gelesen, bevor es die Möglichkeit hatte, den Master zu replizieren.

Eine solche Konfiguration kann in Django mit Hilfe von Datenbankroutern eingerichtet werden, oder sie kann auf der DB-Seite mit einem DB-Proxy erfolgen. Schau dir das an.

Verwandte Themen