Hi all,
using Django 1.8.3, at this time I have code like this:
try:
mm = TestMonthModel.objects.select_for_update().get(jahr=Jahr, monat=Monat)
except TestMonthModel.DoesNotExist:
mm = TestMonthModel(jahr=Jahr, monat=Monat)
# A *long* computation, eventually setting fields in mm and save:
mm.value = 123
mm.save()
With the select_for_update(), this should block any concurrent calls and thus prevent
race conditions whenever the mm object already exists.
But what if it doesn't, and is only created in the except-clause?
There is a unique_together = (jahr, monat) database constraint in place, and thus a
concurrent call to mm.save() would see an IntegrityError for newly created mm objects,
but I wonder if a lock can be acquired after object creation? For example:
try:
mm = TestMonthModel.objects.select_for_update().get(jahr=Jahr, monat=Monat)
except TestMonthModel.DoesNotExist:
mm = TestMonthModel(jahr=Jahr, monat=Monat)
# This is not atomic... is there a better way?
mm.value = 0 # Db constraint, cannot be NULL, so fill in some defaults...
mm.save()
mm = TestMonthModel.objects.select_for_update().get(id=
mm.id)
# Rest as above:
# A *long* computation, eventually setting fields in mm and save:
mm.value = 123
mm.save()
Is select_for_update().get_or_create(...) an option here?
Many thanks and best regards,
Carsten