sql >> Databasteknik >  >> RDS >> PostgreSQL

Selleri och transaktion.atomic

Som @dotz nämnde , det är knappast användbart att skapa en asynkron uppgift och omedelbart blockera och fortsätta vänta tills den är klar.

Dessutom, om du kopplar till det på detta sätt (.get() i slutet), kan du vara säker på att mymodel instansändringar som just gjorts kommer inte att ses av din arbetare eftersom de inte kommer att begås ännu - kom ihåg att du fortfarande är inne i atomic blockera.

Vad du kan göra istället (från Django 1.9) är att fördröja uppgiften tills efter att den aktuella aktiva transaktionen har genomförts, med django.db.transaction.on_commit krok:

from django.db import transaction

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

Jag använder det här mönstret ganska ofta i min post_save signalhanterare som utlöser viss bearbetning av nya modellinstanser. Till exempel:

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))

På det här sättet kommer dock din uppgift inte att utföras om databastransaktionen misslyckas. Det är vanligtvis det önskade beteendet, men tänk på det.

Redigera :Det är faktiskt trevligare att registrera on_commit selleriuppgiften på detta sätt (utan lambda):

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


  1. Har mysql motsvarigheten till Oracles analytiska funktioner?

  2. Utfasad:mysql_connect()

  3. Kontrollera om detta är en dubblett

  4. Heroku Postgres:Den här anslutningen har stängts