2015-05-13 25 views
7

ho un seguente configurazione:Django save() comportamento con le transazioni autocommit

  • Diversi lavoratori di trattamento dei dati di configurazione ottengono dalla vista Django get_conf() da http.
  • configurazione viene memorizzata nel modello di Django utilizza MySQL/InnoDB backend
  • modello di configurazione ha ignorato save() metodo che dice ai lavoratori di ricaricare la configurazione

Ho notato che a volte gli operai non ricevono correttamente la configurazione modificata. In particolare, quando il tempo di ricarica è stato più breve del solito, i lavoratori hanno ottenuto la configurazione "vecchia" da get_conf() (manca la modifica più recente). Il modello di transazione utilizzato in Django è l'autocommit predefinito.

Sono venuto con la seguente possibile scenario che potrebbe causare il comportamento:

  1. Nuova configurazione viene salvata
  2. save() rendimenti ma MySQL/InnoDB sta ancora elaborando la (auto) commettere
  3. Lavoratori sono avviato e fare richiesta HTTP per nuova configurazione
  4. MySQL (auto) commettere finiture

È possibile il passaggio 2 nello scenario sopra riportato? Cioè, è possibile restituire il modello django save() prima che i dati vengano effettivamente impegnati nel DB se viene utilizzato il metodo transazionale autocommit? Oppure, per scendere di un livello, MySQL può eseguire l'autocommitting dell'operazione INSERT o UPDATE prima che il commit sia completato (aggiornamento/inserimento visibile ad altre transazioni)?

+0

Stai utilizzando InnoDB o MyISAM per il tuo motore? – FlipperPA

+0

InnoDB. Il DB è in esecuzione su Amazon RDS con configurazione predefinita.Esistono alcune tabelle di grandi dimensioni, ma le tabelle relative a questo problema sono piccole (dell'ordine di 128 kb o giù di lì) – jhonkola

+0

È possibile disattivare l'autocommit solo per questo caso? – sobolevn

risposta

0

Questo appare decisamente come una condizione di competizione.

Lo scenario che descrivi non dovrebbe mai accadere se c'è solo uno script e un database. Quando si salva(), il metodo non viene restituito finché i dati non vengono effettivamente commessi nel database.

Se si sta utilizzando una configurazione master/slave, si potrebbe essere vittima del ritardo di replica: se si scrive sul master ma si leggono gli slave, è del tutto possibile che lo script non aspetti abbastanza a lungo perché si verifichi la replica, e tu hai letto il vecchio conf dello slave prima che avesse l'opportunità di replicare il master.

Tale configurazione può essere configurata in django utilizzando i router di database oppure può essere eseguita sul lato DB utilizzando un proxy DB. Controlla quello.