title: Django concurrency issues/race condition when multiple requests require access to the same object?
body: <p>My application sends out review requests to multiple users and should cancel (obsolete) all other related requests when one user accepts one of the related requests. Here is what the model looks like:</p>
  <pre><code>class ReviewRequest(models.Model):
  
      class Status(models.IntegerChoices):
          DISPATCHED = 0
          ACCEPTED = 1
          REJECTED = 2
          CANCELLED = 3
          COMPLETED = 4
          OBSOLETED = 5 #TODO: expired?
  
      version = models.ForeignKey(Version, models.SET_NULL, null=True)
      reader = models.ForeignKey(Reader, models.SET_NULL, null=True)
      status = models.IntegerField(choices=Status.choices, default=Status.DISPATCHED)
      rating = models.FloatField(null=True, blank=True)
      reqs_to_obsolete = models.ManyToManyField('self') #TODO: look into race condition here
  </code></pre>
  <p>Suppose two readers accept review requests req1 and req2 at the same time in two different threads A and B. This is something I anticipated can happen:</p>
  <pre><code>A: sees req1.status is DISPATCHED
  A: sees all req1.reqs_to_obsolete have status DISPATCHED
  B: sees req2.status is DISPATCHED
  B: sees all req2.reqs_to_obsolete have status DISPATCHED
  A: req1.status set to ACCEPTED
  B: req2.status set to ACCEPTED
  </code></pre>
  <p>At this point both threads would end up marking the other review request as OBSOLETE, meaning neither party would be able to complete the request.</p>
  <p>Is this actually possible as I've identified? From what I understand, Django handles request in multiple threads, so I can imagine I might need to get a lock on all the related review requests before updating the status:</p>
  <pre><code>A: acquires lock on req1 and all reqs_to_obsolete
  A: sees req1.status is DISPATCHED
  A: sees all req1.reqs_to_obsolete have status DISPATCHED
  B: must wait for lock on req2 before proceeding
  </code></pre>
  <p>Are there any steps I can take to avoid it? Is it easy to implement locks on Django models?</p>