2

我正在实现一个文档服务器。目前,如果两个用户打开同一个文档,然后对其进行修改并保存更改,则文档的状态将是未定义的(第一个用户的更改被永久保存,或者第二个用户的更改)。这完全不能令人满意。我考虑了解决这个问题的两种可能性:

第一种是第一次打开文档时锁定,关闭时解锁。但如果与服务器的网络连接突然中断,文档将处于永久锁定状态。显而易见的解决方案是定期向服务器发送 ping。如果服务器没有连续接收到来自特定客户端的 K 个 ping (K > 1),则由该客户端锁定的文档将被解锁。如果该客户再次出现,文档将再次被锁定,如果有人尚未锁定它们。如果客户端应用程序(在 Web 浏览器中运行)意外终止,这也可能会有所帮助,从而无法向服务器发送“退出,解锁我的文档”信号。

二是存储不同用户保存的同一文档的多个版本。如果快速连续地对文档进行更改,系统将提供合并版本或选择首选版本。为了优化存储空间,应该只保留文档差异(就像源代码控制软件一样)。

考虑到与服务器的连接有时可能很慢且无响应,我应该选择哪种方法?应该如何确定参数(ping 间隔、快速连续间隔)?

PS 不幸的是,我无法将文档存储在数据库中。

4

3 回答 3

1

您描述的第一个选项本质上是悲观锁定模型,而第二个选项是乐观模型。选择哪一个实际上取决于许多因素,但基本上归结为企业希望如何运作。例如,如果他们需要编辑的文档被另一个用户锁定,会不会给用户带来过度的不便?如果文档被锁定并且有人在与他们的客户端连接的情况下去度假会发生什么?每个文档的可能争用是什么——即两个用户同时修改同一个文档的可能性有多大?单个文档中修改的本地化程度如何?(如果定期修改同一部分,则执行合并可能比简单地再次进行更改需要更长的时间)。

假设争用相对较低和/或每个更改的大小相当小,那么我可能会选择一个乐观模型,该模型使用自动或手动合并来解决冲突。文档内容的版本号或校验和可用于确定是否需要合并。

于 2008-08-13T13:26:57.580 回答
0

我的建议会像你的第一个。当第一个用户(Bob)打开文档时,他会获得一个锁,以便其他用户只能阅读当前文档。如果用户在使用文档时保存了文档,他将保持锁定状态。只有当他退出文档时,它才被解锁,其他人可以编辑它。

如果第二个用户 (Kate) 在 Bob 锁定文档时打开文档,Kate 将收到一条消息,指出文档不可编辑,但她可以阅读它,直到锁定被释放。

那么当 Bob 获得锁时会发生什么,可能会保存文档一两次,但随后退出应用程序而使锁处于挂起状态?

正如您自己所说,要求具有锁的客户端以特定频率发送 ping 可能是最好的选择。如果您在一定时间内没有从客户端收到 ping,这实际上意味着他的客户端不再响应。如果这是一个 Web 应用程序,您可以使用 javascript 进行 ping。上次保存的文档释放了它的锁定,Kate 现在可以获取它。

ping 可以包含客户端锁定的文档的名称,并且服务器可以计算收到该文档的最后一次 ping 的时间。

于 2008-08-13T12:10:43.240 回答
0

目前,文件由有限的一组人发布,每个人都在一个单独的主题上工作。因此,锁带来的不便被最小化了。人们大多扩展现有文档并纠正其中的错误。

谈到悲观模型,可以通过将锁定到期日期设置为锁定开始日期前一天来避免“左客户端连接 N 天”的情况。因为编辑的文档绝不是关键任务,并且很少被多个用户修改,这可能就足够了。

现在考虑乐观模型。如果文档有一些规则的(比如,分层的)结构,应该如何检测差异?如果不?在这些情况下,自动合并成功的机会有多大?

情况变得更加复杂,因为一些文档(由 'admins' 用户组编辑)包含重要的配置信息(文档全局索引、用户角色等)。在我看来,锁对于这类信息更有利,因为它不是每天都在变化的。所以一些混合解决方案可能是可以接受的。

你怎么看?

于 2008-08-13T14:07:32.273 回答