OpenERP 框架确实支持并发控制,以防止由于对相同文档的并发修改而导致数据丢失,即使这不是常见问题(见下文原因)。
这个机制是通过乐观并发控制(OCC)实现的,并且从 OpenERP 5.0 开始就存在。悲观锁定不是一种选择,在基于 Web 的无状态环境(用户可以随时离开办公桌)中非常不切实际,并且在资源争用方面通常是一个糟糕的解决方案。大多数具有并发控制机制的现代框架都使用 OCC(Rails、Google App Engine 等)
警告:OpenERP 7.0 目前存在一个突出的错误,导致 Web 界面跳过此机制并忽略并发编辑冲突。不过,框架支持已经存在,并且可以由自定义客户端使用。
执行
OpenERP 的 OCC 实施依赖于使用虚拟__last_update
字段,客户可以在任何模型上作为常规read()
调用的一部分显式请求该字段。默认情况下,该值是从框架在任何记录上维护的write_date
和字段中自动推断出来的。create_date
当客户端稍后write()
对同一条记录进行调用时,它可以传递一个包含原始值的额外上下文结构__last_update
,如果在此期间记录已更新,系统将自动引发错误。_check_concurrency()
有关详细信息,请参阅方法。
当发生这种情况时,客户端堆栈可以做出适当的反应,例如通过显示记录详细信息并询问用户他想强制更新(在这种情况下__last_update
可以简单地更新值)或丢弃她的本地更改。
实际使用
在实践中,这种并发检查有用的情况非常少见。业务文档可以分为两类:主数据(合作伙伴、产品等)记录是长期对象,而运营数据(发票、采购订单等)是短期工作流支持的对象。
操作数据记录通常一次由一个负责的用户管理,并且在创建后,它们主要接收工作流状态更新和新的历史日志条目,这些对于并发更新是安全的(一切都是事务性的)。
主数据记录更容易收到并发更新,但由于 OpenERP 客户端只保存实际修改过的字段,因此在实践中发生冲突的可能性非常有限。
此外,OCC 机制是按记录而不是按字段的,因此它倾向于阻止不一定会发生冲突的编辑(例如针对不同的字段,或在多值字段中添加额外的值)。
一般来说,用户往往会在一段时间后忽略并发错误,如果客户端提供该解决方案选项,则会心不在焉地点击“强制更新”,进一步降低其有用性......