2017-11-01 2 views
1

Ich habe ein Django 1.11 + MySQL + Sellerie 4.1-Projekt, bei dem eine Ansicht einen neuen Benutzerdatensatz erstellt und dann eine Sellerie-Aufgabe startet, um zusätzliche lang andauernde Aktionen in Bezug darauf auszuführen.Wie kann man sicherstellen, dass Django-Modelle vor der Ausführung der Sellerie-Aufgabe gespeichert werden?

Das typische Problem in diesem Fall besteht darin sicherzustellen, dass die Benutzererstellung für die Datenbank festgeschrieben wird, bevor die Sellery-Task ausgeführt wird. Andernfalls gibt es eine Race-Bedingung, und die Task kann versuchen, auf einen Datensatz zuzugreifen, der nicht beendet wird, wenn er ausgeführt wird, bevor die Transaktion festgeschrieben wird.

Die Art, wie ich gelernt hatte, dies zu beheben, bestand darin, die Aufnahmeerstellung immer in eine manuelle Transaktion oder einen atomaren Block zu verpacken und danach die Sellerie-Aufgabe auszulösen. z.B.

def create_user(): 
    with transaction.atomic(): 
     user = User.objects.create(username='blah') 
    mytask.apply_async(args=[user.id]) 

@task 
def mytask(user_id): 
    user = User.objects.get(id=user_id) 
    do_stuff(user) 

Allerdings sehe ich noch gelegentlich den Fehler DoesNotExist: User matching query does not exist in meinem Sellerie Arbeiter logs, was bedeutet, meine Aufgabe manchmal ausgeführt wird, bevor der Benutzerdatensatz begangen wird.

Ist das nicht die richtige Strategie, oder implementiere ich sie nicht richtig?

+0

Offenbar müssen Sie einen 'on_commit'-Hook mit Ihrer Transaktion verwenden: https://docs.djangoproject.com/en/1.11/topics/db/transactions/#django.db.transaction.on_commit –

+0

Mögliche Duplikate von [Sellerie und transaction.atomic] (https://stackoverflow.com/questions/26942604/sellery-and-transaction-atomic) –

Antwort

Verwandte Themen