Monday, September 6, 2010

How do you avoid this race condition in Django?

I have a model MyModel that has a field expiration_datetime.

Every time a user retrieves an instance of MyModel I need to first
check if it has expired or not. If it has expired, than I need to
increment some counter, update others, and then reset the
expiration_datetime to some time in the future.

So the view would do something like:

if object.expiration_datetime < datetime.datetime.now():
object.counter = F('counter') + 1
object.expiration_datetime = F('expiration_datetime') +
datetime.timedelta(days=1)
object.save()

There's a race condition in the code above. Say thread 1 checks and
finds that the current instance has expired, it proceeds to increment
the counter and reset the expiration datetime. But before it could do
so, thread 2 is scheduled and does the same. By the time thread 1
finally finishes, counter has been incremented twice and
expration_datetime has been reset twice.

This looks like a pretty common issue. How do I handle it?

--
You received this message because you are subscribed to the Google Groups "Django users" group.
To post to this group, send email to django-users@googlegroups.com.
To unsubscribe from this group, send email to django-users+unsubscribe@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/django-users?hl=en.

No comments:

Post a Comment