I have a function fn()
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).
What is the correct way to implement this in Django? Basically I'd like to do something like this:
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()
@transaction.atomic
takes care of part of the problem (database should only ever see the state before fn
runs or after fn
runs successfully), but I'm not sure if there exists a good primitive to do the commit_only_if_the_data_actually_didnt_change
, and retrying the operation if it fails.
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.