Monday, July 27, 2015

Transaction questions

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

--
You received this message because you are subscribed to the Google Groups "Django users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to django-users+unsubscribe@googlegroups.com.
To post to this group, send email to django-users@googlegroups.com.
Visit this group at http://groups.google.com/group/django-users.
To view this discussion on the web visit https://groups.google.com/d/msgid/django-users/55B6788A.3000804%40cafu.de.
For more options, visit https://groups.google.com/d/optout.

No comments:

Post a Comment