PostgreSQL
 sql >> Base de Dados >  >> RDS >> PostgreSQL

Aipo e transação.atomic


Como @dotz mencionou , dificilmente é útil gerar uma tarefa assíncrona e bloquear imediatamente e continuar esperando até que ela termine.

Além disso, se você anexar a ele dessa maneira (o .get() no final), você pode ter certeza de que o mymodel as alterações de instância feitas não serão vistas pelo seu trabalhador porque ainda não serão confirmadas - lembre-se de que você ainda está dentro do atomic quadra.

O que você pode fazer em vez disso (a partir do Django 1.9) é atrasar a tarefa até que a transação ativa atual seja confirmada, usando django.db.transaction.on_commit gancho:
from django.db import transaction

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

Eu uso esse padrão com bastante frequência no meu post_save manipuladores de sinal que acionam algum processamento de novas instâncias de modelo. Por exemplo:
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))

Dessa forma, no entanto, sua tarefa não será executada se a transação do banco de dados falhar. Geralmente é o comportamento desejado, mas mantenha-o em mente.

Editar :Na verdade, é melhor registrar a tarefa de aipo on_commit dessa maneira (sem lambda):
transaction.on_commit(tasks.process_new_order.s(instance.pk).delay)