我正在使用breeze在我的SPA和网络服务器之间进行交互,并且可以使用一些有关并发“问题”的帮助。
只要更新是一个简单的对象,并发工作正常。但是,在处理分层实体时,问题就开始了。
例如,产品具有一些简单的属性,如代码,名称,描述以及一些导航属性。为简洁起见,我将仅讨论其中一个:产品包(具有id,代码,名称和productId的实体,这是产品的外键)。保存产品时,只有具有更改的实体才会发送到服务器,因此,如果我们将产品包添加到产品中,那么这只是此产品包实体。
当此产品由2个人同时编辑时,可能会导致问题,例如由于产品包装上发生了一些业务验证。
产品本身具有“版本”属性,因此一个选项可能是在产品包列表(或其他导航属性之一)发生更新时手动将产品实体状态设置为已修改,但是这将需要为每个动作发送产品实体(不是它需要那么多带宽,但感觉就像一个黑客)。
这样的事情的最佳做法是什么?
答案 0 :(得分:1)
我的感觉是你的问题不只是关于锁定而且(或者更确切地说)关于合作编辑,这不是一个可以通过单一答案解决的问题。合作编辑非常复杂,人们可以编写有关它的书籍。根据您的coop编辑会话的要求以及数据的结构如何以及数据的不同节点之间的松散/严格约束/规则/关系,可以有许多解决方案,这些解决方案都不是完美的但是自己的利弊。
我最近一直在合作编辑工具上工作(有时还在工作),所以我对问题的复杂程度有了一定的线索,但不要期待对你的模糊问题有明确的答案,因为你赢了& #39;得到一个。要给你一个好的答案是不可能的,因为正如我之前提到的那样,即使是明确指定的合作编辑问题也常常无法提供一个好的答案,因为每个解决方案都有某种权衡,你必须决定哪个解决方案有适合您的优点和可接受的利弊。例如,您的客户可能更喜欢使用" fluid"会话就好像他单独使用一个桌面应用程序一样,有时会因为隐藏网络延迟而发现冲突而导致其工作回滚,但另一个客户可能更喜欢另一种方式:始终每次更改后提交/验证数据,即使花费时间并以较差的用户体验/较慢的工作为此付费。
分层数据?如何通过锁定并发访问来保护您的数据始终是一个大问题。这里最大的问题是你必须定义什么"一致性"表示您的数据。让我们说有人想写一个小单元,一个"节点"在您的数据中,您必须在实际提交之前验证数据。您不仅要锁定即将更改的节点,还要锁定所需的所有其他节点,以便根据您的规则检查新写入的数据是否与其他节点的内容一致。由于这个非常简单的原因,如果节点之间的关系较少,一致性规则限制较少,则编辑会话变得更有效,锁定更少。尽量使规则尽可能宽松。
以下是一些如何让您的生活更轻松的随机提示:
锁定:
如果您有一个树,如果您有严格的一致性规则,那么您可能想要锁定整个子树,有时只需要更小的子树。这是一个天真的解决方案:你锁定每个节点。如果要锁定子树,则必须在开始处理数据之前锁定该子树中的每个节点。定义节点/锁的顺序,例如,作为树的inorder遍历。当你想要锁定一个子树时,你只需要通过inorder遍历来遍历它,然后逐个获取每个锁。
正如我告诉你的那样,合作编辑有很多算法/方法,它是一个热门话题,你可以使用谷歌找到它们,但我会提到你一个我喜欢的算法。它是一种非常简单但非常有效的算法。当您的数据松散耦合时(当您在编辑时仅锁定单个节点或小单位数据)时,它会产生奇迹:https://neil.fraser.name/writing/sync/
编辑:我忘记了一些事情:在合作编辑中你必须处理冲突,当"玩家" (:-))修改相同的对象"同一"时间。最基本的解决方案属于这两个类别,这些黑白解决方案之间有几种灰色" /中间解决方案:我认为您已经更好地掌握了我所谈论的内容,并且您可以创建无数种组合作为编辑问题的解决方案,即使是我在此处所描述的内容。在编辑程序的情况下,为用户提供彼此通信/协作的方式也是非常重要的。这种沟通可以聊天,但我更喜欢视觉反馈。例如,在合作文档编辑器的情况下,您可以直观地显示其他人正在查看/编辑的位置,在3d世界编辑器的情况下,您可以显示其他用户的选择/锁定区域以及他们的相机的位置。视觉反馈更容易被大脑处理,并且使用非常短的学习曲线更直观。