Như @dotz đã đề cập , sẽ không hữu ích khi tạo ra một tác vụ không đồng bộ và ngay lập tức chặn và tiếp tục đợi cho đến khi nó hoàn thành.
Hơn nữa, nếu bạn đính kèm với nó theo cách này (.get()
ở cuối), bạn có thể chắc chắn rằng mymodel
nhân viên của bạn sẽ không nhìn thấy các thay đổi phiên bản vừa thực hiện vì chúng chưa được cam kết - hãy nhớ rằng bạn vẫn đang ở bên trong atomic
khối.
Thay vào đó, những gì bạn có thể làm (từ Django 1.9) là trì hoãn tác vụ cho đến khi giao dịch hiện hoạt hiện tại được cam kết, sử dụng django.db.transaction.on_commit
móc:
from django.db import transaction
with transaction.atomic():
mymodel.save()
transaction.on_commit(lambda:
mytask.delay(mymodel.id))
Tôi sử dụng mẫu này khá thường xuyên trong post_save
của mình các trình xử lý tín hiệu kích hoạt một số quá trình xử lý các phiên bản mô hình mới. Ví dụ:
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))
Tuy nhiên, theo cách này, tác vụ của bạn sẽ không được thực thi nếu giao dịch cơ sở dữ liệu không thành công. Đó thường là hành vi mong muốn, nhưng hãy ghi nhớ nó.
Chỉnh sửa :Thực sự tốt hơn khi đăng ký tác vụ cần tây on_commit theo cách này (w / o lambda):
transaction.on_commit(tasks.process_new_order.s(instance.pk).delay)