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

Selleri og transaktion.atomic

Som @dotz nævnt , er det næppe nyttigt at afføde en async-opgave og straks blokere og blive ved med at vente, indtil den er færdig.

Desuden, hvis du knytter til det på denne måde (.get() til sidst), kan du være sikker på, at mymodel instansændringer, der netop er foretaget, vil ikke blive set af din medarbejder, fordi de ikke vil blive begået endnu - husk, at du stadig er inde i atomic blokere.

Hvad du kunne gøre i stedet (fra Django 1.9) er at forsinke opgaven, indtil den aktuelle aktive transaktion er begået, ved at bruge django.db.transaction.on_commit krog:

from django.db import transaction

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

Jeg bruger dette mønster ret ofte i min post_save signalhandlere, der udløser en vis behandling af nye modelforekomster. For eksempel:

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å denne måde vil din opgave dog ikke blive udført hvis databasetransaktionen mislykkes. Det er normalt den ønskede adfærd, men husk det.

Rediger :Det er faktisk bedre at registrere on_commit selleri opgaven på denne måde (uden lambda):

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


  1. Forvirret over Itzik Ben-Gans logiske forespørgselsbehandlingsrækkefølge i hans SQL Server 2005-bog og SQL Server 2008-bog

  2. Hvorfor ændres ora_rowscn uden at opdatere en tabel

  3. hvorfor producerer denne MySQL-forespørgsel de forkerte rækkenumre?

  4. Alternativ til django.db.close_connection()