[Answer]-Celery periodic_task in Django run once(!)

1👍

✅

You could use transactions:

@periodic_task(run_every=datetime.timedelta(seconds=2))
@transaction.commit_on_success
def initialize_new_jobs():
    for obj in Queue.objects.select_for_update().filter(status__in=['I', 'Q']):
        obj.status = 'A'
        obj.save()
        create_other_task.delay(obj.id)

select_for_update() puts an exclusive lock on rows so that other users get blocked when attempting to read the values. The lock is released after the transaction has been committed or rolled back. Reference.

This way you can be sure that the obj has status of I or Q and that the obj.save() will work properly.

👤Maciej Gol

Leave a comment