PostgreSQL
 sql >> Database >  >> RDS >> PostgreSQL

Sedano e transazione.atomico

Come @dotz menzionato , è poco utile generare un'attività asincrona e bloccarla immediatamente e continuare ad aspettare fino al termine.

Inoltre, se lo alleghi in questo modo (il .get() alla fine), puoi essere sicuro che il mymodel le modifiche alle istanze appena apportate non verranno visualizzate dal tuo lavoratore perché non verranno ancora salvate:ricorda che sei ancora all'interno di atomic blocco.

Quello che potresti fare invece (da Django 1.9) è ritardare l'attività fino a dopo il commit della transazione attiva corrente, usando django.db.transaction.on_commit gancio:

from django.db import transaction

with transaction.atomic():
    mymodel.save()
    transaction.on_commit(lambda:
        mytask.delay(mymodel.id))

Uso questo modello abbastanza spesso nel mio post_save gestori di segnale che attivano l'elaborazione di nuove istanze del modello. Ad esempio:

from django.db import transaction
from django.db.models.signals import post_save
from django.dispatch import receiver
from . import models   # Your models defining some Order model
from . import tasks   # Your tasks defining a routine to process new instances

@receiver(post_save, sender=models.Order)
def new_order_callback(sender, instance, created, **kwargs):
    """ Automatically triggers processing of a new Order. """
    if created:
        transaction.on_commit(lambda:
            tasks.process_new_order.delay(instance.pk))

In questo modo, tuttavia, il tuo compito non verrà eseguito se la transazione del database non riesce. Di solito è il comportamento desiderato, ma tienilo a mente.

Modifica :In realtà è più bello registrare l'attività di sedano on_commit in questo modo (senza lambda):

transaction.on_commit(tasks.process_new_order.s(instance.pk).delay)