django-concurrency is an optimistic locking library for Django Models
It prevents users from doing concurrent editing in Django both from UI and from a django command.
django-concurrency requires Django >= 1.4
- easy to add to existing Models (just add concurrency.fields.VersionField )
- works with third-party models (see apply_concurrency_check())
- works with Django internal models
- handle http post and standard python code (ie. django management commands)
- complete test suite (Test suite)
- works with South and diango-reversion
- Admin integration. Handle actions and list_editable (solves issue #11313)
- can handle external updates (see TriggerVersionField)
How it works¶
django-concurrency works adding a concurrency.fields.VersionField to each model, each time a record is saved the version number changes (the algorithm used depends on the implementation of concurrency.fields.VersionField used (see Fields).
django-concurrency use two different way to manage concurrent updates:
django 1.4 - 1.5¶
When a record is saved, django-concurrency tries to get a lock on the record based on the old revision number, if the record is not found a RecordModifiedError is raised. The lock is obtained using SELECT FOR UPDATE and it’s requirend to prevent other updates during the internal django save() execution.
django >= 1.6¶
Full implementation of optimistic-lock pattern using a SQL clause like:
UPDATE mymodel SET version=NEW_VERSION, ... WHERE id = PK AND version = VERSION_NUMBER
Why two protocols ?¶
The initial implementation of django-concurrency used the real pattern , but it required a partial rewrite of original Django’s code and it was very hard to maintain/keep updated, for this reason starting from version 0.3, select_for_update() was used.
With the new implementation (django 1.6) the optimistic lock pattern it is easier to implement. Starting from version 0.7 django-concurrency uses different implementation depending on the django version used.
From 1.0 support for django < 1.6 will be drooped