siddharth jambukiya
siddharth jambukiya

Reputation: 381

No concurrency check when updating records

Only one user at any time should be able to edit a contract. We need to pop up a dialog box with details of the user that has the record open if another user tries to edit the record.

This obvious feature doesn't appear to be native to OpenERP.

Is there a module that implements this across the whole system?

Only one user at any time should be able to edit a contract. We need to pop up a dialog box with details of the user that has the record open if another user tries to edit the record. The 2nd user should then be prevented from editing the record until it is unlocked (i.e. the 1st user either saves or discards the record).

Seems odd that record locking is not part of the default Openerp architecture - do you know why?

Can we take a look at how we can implement this and come back with some ideas. It's not a burning priority at the moment but will be as soon as one/two of the users "discover" this issue.

Upvotes: 2

Views: 2266

Answers (1)

odony
odony

Reputation: 4117

The OpenERP framework does support concurrency control to prevent loss of data due to concurrent modifications of the same documents, even if this is not a common problem (see below why).

This mechanism is implemented via Optimistic Concurrency Control (OCC), and exists since OpenERP 5.0. Pessimistic locking is not an option, being quite impractical in a stateless web-based environment (where users can leave their desk at any time), and generally a bad solution in terms of resource contention. Most modern framework with a concurrency control mechanism use OCC (Rails, Google App Engine, etc.)

Warning: There is currently an outstanding bug in OpenERP 7.0 that causes the web interface to skip this mechanism and ignore concurrent editing conflicts. The framework support is there and can be used by custom clients, though.

Implementation

OpenERP's OCC implementation relies on the use of a virtual __last_update field that clients can requests explicitly as part of regular read() calls, on any model. The value is automatically inferred from the write_date and create_date fields that the framework maintains on any record by default. When the client later makes a write() call on the same record, it can pass an extra context structure containing the original __last_update value, and the system will automatically raise an error if the record has been updated in the meantime. See the _check_concurrency() method for more details.

When this occurs the client stack can react as appropriate, for example by showing the record details and asking the user he she'd like to force an update (in which case the __last_update value can simply be updated) or discard her local changes.

Practical Use

In practice, the cases were such a concurrency check are useful are quite rare. Business documents can be divided up in two classes: master data (Partners, Products, etc.) records are long-lived objects, vs operational data (Invoices, Purchase Orders, etc.), short-lived workflow-supported objects.

Operational data records are usually managed by a single responsible user at a time, and after creation they mostly received workflow state updates and new history log entries, which are safe for concurrent updates (everything is transactional).

Master data records are more likely to receive concurrent updates, but because the OpenERP clients only save fields that have actually been modified, the chances of conflicts are quite limited in practice.

In addition, the OCC mechanism is per-record but not per-field, so it tends to block edits that would not necessarily conflict (targeted at different fields, or added extra values in multi-valued fields, for example).

In general, users tend to ignore the concurrency errors after a while, and will click absentmindedly on "Force update" if the client offers that resolution option, further reducing its usefulness...

Upvotes: 4

Related Questions