title: How to avoid race condition with unique checks in Django
body: <p>I have a simple model:</p>
  
  <pre class="lang-py prettyprint-override"><code>class InvitationRequest(models.Model):
      email = models.EmailField(max_length=255, unique=True)
  </code></pre>
  
  <p>And a simple model form:</p>
  
  <pre class="lang-py prettyprint-override"><code>class InvitationRequestForm(forms.ModelForm):
      class Meta:
          model = InvitationRequest
  </code></pre>
  
  <p>Now, assuming that I attempt to process it in a standard way:</p>
  
  <pre class="lang-py prettyprint-override"><code>form = InvitationRequestForm(request.POST)
  if form.is_valid():
      form.save()
  </code></pre>
  
  <p>There is a race condition because validation performs a simple <code>SELECT</code> query to determine whether or not such email is already stored, and if everything is fine then it proceeds to <code>form.save()</code> line. If there is a concurrent process that does the same at exactly the same moment, then both forms will validate and both processes will call <code>form.save()</code> thus one will succeed and the other will fail causing an <code>IntegrityError</code>.</p>
  
  <p><strong>What is the standard way to handle this?</strong></p>
  
  <p>I want to have a standard error in the form object so I can pass it on to the template and notify user about the problem.</p>
  
  <p>I know that:</p>
  
  <ul>
  <li>I can wrap everything with try/except and add new error to my form manually</li>
  <li>I can wrap everything with <code>SERIALIZABLE</code> transaction (in MySQL as it performs next key locking fo every select then)</li>
  <li>I can use override <code>Model._perform_unique_checks</code> and make
  it use <code>select_for_update</code> (works with MySQL because of next key locking)</li>
  <li>I can acquire table-level exclusive lock</li>
  </ul>
  
  <p>None of these solutions is appealing, also I am using PostgreSQL which differs from MySQL in this area.</p>