2008-08-13 25 views
2

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

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

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

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

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

回答

0

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

如果第二个用户(凯特)打开该文档,而鲍勃上有锁,凯特将得到一个消息,说该文件是不可编辑的,但她能读它,直到它的锁已被释放。

那么当Bob获得锁定时,会发生什么情况,可能会保存文档一两次,然后退出应用程序而将锁挂起?

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

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

1

您描述的第一个选项本质上是一个悲观锁定模型,而第二个选项是乐观模型。 要选择哪一种方法真的可以归结为许多因素,但本质上归结为企业想要如何工作。例如,如果他们需要编辑的文档被其他用户锁定,会不会给用户造成不便?如果文档被锁定并且有人与他们的客户端连接在一起度假,会发生什么?每个文档可能存在什么争议 - 即两个用户同时修改同一文档的可能性有多大?修改可能在单个文档中的本地化程度如何?(如果定期修改同一部分,则执行合并可能需要的时间比再次进行更改所需的时间更长)。

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

0

当前文档由有限的一组人员发布,他们每个人都在单独的主题上工作。所以,由锁引入的不便之处被最小化。 人们主要是扩展现有文档并纠正错误。

说到悲观模型,通过将锁定过期日期设置为锁定开始日期前一天,可以避免'连接N天'的情况。由于编辑的文件绝不是关键任务,并且很少被多个用户修改,所以这可能就足够了。

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

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

您认为如何?