title: Release Celery lock when transaction is committed
body: <p>I use a Celery task in my Django project with a lock as described in <a href="http://docs.celeryproject.org/en/latest/tutorials/task-cookbook.html#ensuring-a-task-is-only-executed-one-at-a-time" rel="nofollow noreferrer">this article</a>. It works great, but my task creates an object and I don't want that the lock was released before the object is committed in the database. How can I change this context manager to wait until the objects in the task are committed?</p>
  
  <pre><code>@contextmanager
  def lock(lock_id, oid, expire=600):
      timeout_at = monotonic() + expire - 3
      status = cache.add(lock_id, oid, expire)
      try:
          yield status
      finally:
          if monotonic() &lt; timeout_at:
              cache.delete(lock_id)
  
  @celery.task(bind=True, ignore_result=True)
  def my_task(self, object_id):
      with lock('my_task.{}'.format(object_id), self.app.oid) as acquired, transaction.atomic():
          if not acquired:
              self.retry(countdown=1)
          def on_commit():
              # release the lock only in this moment
              pass
          transaction.on_commit(on_commit)
          MyModel.objects.create(object_id=object_id)
  </code></pre>