Sto provando a combattere alcuni casi di gara con il mio task manager in background. Essenzialmente, ho un oggetto Thing
(già esistente) e gli assegno alcune proprietà, quindi lo salvo. Dopo che è stato salvato con le nuove proprietà, lo accodo in Resque, passando l'ID.Esegui codice rails dopo l'aggiornamento di un aggiornamento al database, senza after_commit
thing = Thing.find(1)
puts thing.foo # outputs "old value"
thing.foo = "new value"
thing.save
ThingProcessor.queue_job(thing.id)
Il processo in background caricherà l'oggetto dal database utilizzando Thing.find(thing_id)
.
Il problema è che abbiamo riscontrato che Resque è così veloce nel riprendere il lavoro e nel caricare l'oggetto dall'ID, che carica un oggetto non aggiornato. Quindi all'interno del lavoro, chiamare thing.foo
restituirà ancora "valore precedente" come 1/100 volte (non dati reali, ma non succede spesso).
Sappiamo che questo è un caso di gara, perché le rotaie torneranno da thing.save
prima che i dati è stato effettivamente commesso al database (PostgreSQL in questo caso).
Esiste un modo in Rails per eseguire solo il codice DOPO che un'operazione di database è stata eseguita? Essenzialmente, voglio assicurarmi che quando Resque carica l'oggetto, sta ottenendo l'oggetto più fresco. So che questo può essere ottenuto utilizzando un gancio after_commit
sul modello Thing
, ma non lo voglio lì. Ho solo bisogno che ciò avvenga in questo contesto specifico, non ogni volta che il modello è stato commutato nel DB.
Quindi, l'esecuzione di una transazione bloccherà l'esecuzione di 'ThingProcessor.queue_job (thing.id)' finché tutte le query nel blocco di transazione non si saranno impegnate? Pensavo che i blocchi di transazione si assicurassero che se si verificava un errore in qualsiasi azione del database all'interno del blocco, tutto veniva annullato. Una funzionalità di database. Non un rubino – Brian
Credo di sì. Fai un tentativo e fammi sapere se funziona. –
Impossibile trovare la documentazione di Rails che dice che un blocco di transazione blocca l'esecuzione. Qualcuno sa in modo definitivo? – Ben