Wednesday, October 28, 2015

Re: Locking / serializing access to one element in database

Hi Collin, hi all,

Am 27.10.2015 um 19:56 schrieb Collin Anderson:
> Yes, an exception will be raised.

Thinking further about this, all we need is a method that gives us an exception if we
accidentally create a second object when in fact only one is wanted. Your suggestion
with manually dealing with the PKs and using .save(force_insert=True) is one method to
achieve that, another one that works well for me is using an (application-specific)

unique_together = (year, month)

constraint, which achieves the desired result (guarantee uniqueness where required,
raise an exception otherwise) without having to manually deal with PKs.

Alas, I wonder how to proceed to complete the solution. As I find it simpler to deal
with the above mentioned unique_together rather than with coming up with a PK based
solution, I refer to my original code from [1], which was:


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()


Combining everything from this thread, this could be changed into this code
(pseudo-code, not tested):


while True:
try:
mm = TestMonthModel.objects.select_for_update().get(jahr=Jahr, monat=Monat)
break # Got what we wanted!
except TestMonthModel.DoesNotExist:
try:
# Create the expected but missing instance.
# No matter if the following succeeds normally or throws
# an Integrity error, thereafter just restart the loop.
TestMonthModel(jahr=Jahr, monat=Monat).save()
except IntegrityError:
pass

# A *long* computation, eventually setting fields in mm and save:

mm.value = 123
mm.save()


Afaics, this solves the problem, but it also feels quite awkward and I wonder if there
is a more elegant solution.

Comments? Does this sound reasonable at all?

Best regards,
Carsten

[1] https://groups.google.com/forum/#!topic/django-users/SOX5Vjedy_s

--
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/563126B1.9090609%40cafu.de.
For more options, visit https://groups.google.com/d/optout.

No comments:

Post a Comment