文件服务器:处理并发保存

时间:2008-08-13 11:49:14

标签: concurrency locking versioning

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

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

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

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

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

3 个答案:

答案 0 :(得分:1)

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

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

答案 1 :(得分:0)

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

如果第二个用户(Kate)在Bob锁定文档时打开文档,Kate将收到一条消息,说明该文档是不可编辑的,但是在锁定被释放之前,她可以阅读该文档。

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

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

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

答案 2 :(得分:0)

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

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

现在考虑乐观模型。如果文档具有一些常规(例如,分层)结构,应该如何检测差异?如果不?在这些情况下成功自动合并的几率是多少?

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

您怎么看?