Transaction questions

27 views
Skip to first unread message

Carsten Fuchs

unread,
Jul 27, 2015, 2:30:31 PM7/27/15
to Django users
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

Reply all
Reply to author
Forward
0 new messages