Dear Django group,
please consider this code:
from datetime import date
from django.db import models
class TestModel(models.Model):
jahr = models.SmallIntegerField()
monat = models.SmallIntegerField()
some_value = models.SmallIntegerField()
class Meta:
unique_together = ('jahr', 'monat')
def demonstrate_the_problem():
d = date.today()
try:
t = TestModel.objects.get(jahr=d.year, monat=d.month)
# t exists, no need to create or modify it.
return t.some_value
except TestModel.DoesNotExist:
# t did not yet exist, so we have to create it anew.
# Note that there is a "unique together" constraint in place
# that makes sure that the tuple (jahr, monat) only exists once.
# Thus we create a new instance, then lock it with
# select_for_update() -- but this is still not atomic!
TestModel(jahr=d.year, monat=d.month).save()
t = TestModel.objects.get(
jahr=d.year, monat=d.month).select_for_update()
# A long computation, eventually setting fields in the new t,
# then saving it for the next call to this function.
t.some_value = 123
t.save()
return t.some_value
The problem is that another thread too may have created a TestModel with the
same (jahr, monat) in the timespan between our "does not exist" and "lock",
triggering a violation of the "unique" constraint.
Thus, the question is how we can make the sequence "does not exist – create anew
– lock" atomic?
Any feedback would very much be appreciated!
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 [email protected].
To post to this group, send email to [email protected].
Visit this group at https://groups.google.com/group/django-users.
To view this discussion on the web visit
https://groups.google.com/d/msgid/django-users/5733370C.2050001%40cafu.de.
For more options, visit https://groups.google.com/d/optout.