Django: How can I protect against concurrent modification of database entries

This is how I do optimistic locking in Django:

updated = Entry.objects.filter(Q(id=e.id) && Q(version=e.version))\
          .update(updated_field=new_value, version=e.version+1)
if not updated:
    raise ConcurrentModificationException()

The code listed above can be implemented as a method in Custom Manager.

I am making the following assumptions:

  • filter().update() will result in a single database query because filter is lazy
  • a database query is atomic

These assumptions are enough to ensure that no one else has updated the entry before. If multiple rows are updated this way you should use transactions.

WARNING Django Doc:

Be aware that the update() method is
converted directly to an SQL
statement. It is a bulk operation for
direct updates. It doesn’t run any
save() methods on your models, or emit
the pre_save or post_save signals

Leave a Comment