title: Optimistic "locking" with Django transactions
body: <p>I have a function <code>fn()</code> that needs to atomically do some database work that relies on some set of data not changing during its execution (true most of the time). </p>
  
  <p>What is the correct way to implement this in Django? Basically I'd like to do something like this:</p>
  
  <pre><code>def ensure_fn_runs_successfully():
    # While commit unsuccessful, keep trying
    while not fn():
      pass
  
  @transaction.atomic
  def fn():
    data = read_data_that_must_not_change()
  
    ... do some operations with the data and perform database operations ...
  
    # Assume it returns true if commit was successful, otherwise false
    return commit_only_if_the_data_actually_didnt_change()
  </code></pre>
  
  <p><code>@transaction.atomic</code> takes care of part of the problem (database should only ever see the state before <code>fn</code> runs or after <code>fn</code> runs successfully), but I'm not sure if there exists a good primitive to do the <code>commit_only_if_the_data_actually_didnt_change</code>, and retrying the operation if it fails. </p>
  
  <p>To verify the data didn't change, it would be enough to just check the count of items returned for a query is the same as it was at the beginning of the function; however, I don't know if there are any primitives that let you make the check and commit decision at the same time / without race condition.</p>