Why is needed?To avoid the loss of information when 2 users update the same object, or even when one user has the same object open in multiples browsers or tabs (database locks nor 'select for update' help here).
Ej: the object with version 'N' is in the DB; the object is shown in the browser by two users (let sey user A and user B). The user A modifies it and save it in the database. The user B modifies the same object, and save it. The changes entered by user A are silently lost, and neither user A nor user B acknowledges the situation.
How it worksIt works the same way as in Hibernate. The instance has a version field, which is sent to the user as a hidden field. Instead of using a simple SQL "UPDATE ...", we use "UPDATE ... WHERE VERSION = YYY", and check how many rows where updated. If no row was updated, it means the version has changed and we report this as an optimistic locking error.
Ej: the current implementation raises an OptimisticLockingError when user B tries to save the changes. The developer has to catch this exception and make whatever he or she wants.
Alternatives to Optimistic Locking
- maybe versioning of attributes (ej: instead of having a "descripcion" field, have a set of "descriptions" and a "current description" foreign key)
- remove requeriment of hard-coded 'version' field, and instead look for any field of type VersionField,
- decide and implement how to manage deletes,
- evaluate alternatives how to enable optimistic locking on models (see 'Alternatives for enabling O.L. on a model'),
- implement graceful handling of optimistic locking errors in admin,
- see how this relates the adoption of NOSQL support or other related topics,
Alternatives for enabling O.L. on a modelWe want to make optimistic locking totally optional and easy to use for existing models and forms. We explored different alternatives to 'mark' that we want optimistic locking semantics for a specific model. Also, we want to avoid introducing new mechanisms. The alternatives were:
1. Add a VersionField to models
This is how it's implemented right now: you add a VersionField to your model. The associated form field uses a HiddenInput widget, so ModelForms don't have to be modified to support optimistic locking, since the version is automatically sent to the browser as a hidden field.
PRO: is explicit (you see a new field being added)
CON: models should have only one VersionField, and the field is kind of magic: if it exists, the model has optimistic locking semantics. There is no comparable mechanism in Django (maybe could be comparable to AutoField?).
--- Example ---
2. Use a Meta option
Allow the user set a Meta option, like 'optimistic_locking = True'.
PRO: it very clean
CON: hides the fact that a new field is added. There is no comparable mechanism in Django (a meta option that adds a field)
--- Example ---
Related Django tickets
- Ramiro Morales <firstname.lastname@example.org>
- Francisco Capdevila <email@example.com>
- Carlos Ilcobich <firstname.lastname@example.org>
- Fernando Flores <email@example.com>
- Matías Bordese <firstname.lastname@example.org>
- Martín Gaitan <email@example.com>
- Horacio G. de Oro <firstname.lastname@example.org>