Javascript 基于时间戳的冲突解决,无需可靠的时间同步

Javascript 基于时间戳的冲突解决,无需可靠的时间同步,javascript,synchronization,timestamp,conflict,Javascript,Synchronization,Timestamp,Conflict,让我们以一个js“应用程序”为例,它基本上执行CRUD,因此它创建、更新和删除(实际上不是)一些“记录” 在最基本的情况下,不需要解决此类应用程序中的冲突,因为DBMS的ACID属性用于删除并发更新(我知道,我在这里浏览了大量详细信息)。当无法模拟更新的串行执行时,可以使用时间戳来确定更新“获胜”的原因。即使这样,客户机也不必担心时间戳,因为它们可以在服务器上的请求时生成 但是,如果我们更进一步,允许更新在客户端排队等待一段不确定的时间(比如,在没有网络连接的情况下允许应用程序工作),然后推送到

让我们以一个js“应用程序”为例,它基本上执行CRUD,因此它创建、更新和删除(实际上不是)一些“记录”

在最基本的情况下,不需要解决此类应用程序中的冲突,因为DBMS的ACID属性用于删除并发更新(我知道,我在这里浏览了大量详细信息)。当无法模拟更新的串行执行时,可以使用时间戳来确定更新“获胜”的原因。即使这样,客户机也不必担心时间戳,因为它们可以在服务器上的请求时生成

但是,如果我们更进一步,允许更新在客户端排队等待一段不确定的时间(比如,在没有网络连接的情况下允许应用程序工作),然后推送到服务器上,会怎么样?然后,无法在服务器上生成时间戳,因为将更新推送到服务器的时间和执行更新的实际时间可能会有很大差异

在理想情况下,所有时钟都是同步的,这不是问题——只要在执行更新时在客户端上生成一个时间戳即可。但在现实中,时间常常偏离“服务器”时间(这被认为是完美的,毕竟,它是由我们来配置服务器的,它会出什么问题?)或者仅仅是几个小时的错误(可能是因为您没有设置时区,而是更新系统的时间/日期以匹配)。在这种情况下,人们会如何解释现实


在这种情况下,也许还有其他解决冲突的方法?

您的问题有两个方面:

  • 通过数据库的ACID属性使用时间戳在服务器上同步/序列化
  • 与客户端连接的队列(服务器不知道的延迟)
  • 若您在客户机上维护队列,当服务器认为合适时将其推送到服务器,那个么它最好有简单的同步。因为它只是违背了时间戳的目的,而时间戳正是服务器所依赖的

    ACID的范围在这里是有限的,因为如果客户端更新不是实时的,它就不能基于创建的请求的时间戳或请求到达的时间戳进行序列化。它创建了一个场景,其中创建晚于请求R1的请求R2在R1之前到达

    时间是一个相对的概念,为客户端或服务器使用本地时间将导致另一个出现漂移。此外,它不可扩展(如果有多个对等节点分布,则效率低下)。它引入了单点故障

    为了解决这个问题,我们设计了。它们是逻辑时钟,当机器上原子地发生事件时,会增加时钟。基本数据库(基本可用、软状态、最终一致性)使用它


    结果是1和2永远不会成功。您不应该对使用时间戳解决冲突的请求排队。

    不错的挑战。虽然我很欣赏anwser,但这就是我在CQRS/DDD应用程序中处理类似情况的方式

    在DDD应用程序中,我有很多不同的命令和查询,而在CRUD应用程序中,对于每种类型的“记录”我们有创建、更新和删除命令以及读取查询

    在我的系统中,在客户机上,我在一个元组中跟踪上一次同步,该元组包含:服务器上的UTC时间、客户机上的时间(我们称之为LastSync

    阅读
    读取查询不会参与同步。不过,在某些情况下,您可能必须向服务器发送一个LogRead命令,以跟踪用于做出决策的信息。此类命令确实包含实体的类型、实体的标识符和LastSync.ServerTime)

    创建
    Create命令根据定义是幂等元:它们要么成功,要么失败(当具有相同标识的记录已经存在时)。在同步时,您必须通知用户冲突(以便他可以处理这种情况,例如通过更改标识符)或修复时间戳,如下文所述

    更新
    更新命令有点棘手,因为您可能应该在不同类型的记录上对它们进行不同的处理。为了保持简单,您应该能够强制用户上一次更新总是获胜,并将命令设计为只携带应该更新的属性(就像SQL update语句一样)。否则,您将不得不处理自动/手动合并(但请相信我,这只是一个夜晚:大多数用户永远不会理解!)最初,我的客户对大多数实体都需要此功能,但过了一段时间,他们接受了上一次更新的成功,以避免这种复杂性。此外,如果对已删除对象进行更新,则应将情况通知用户,并根据更新的实体类型,应用或不应用更新

    删除
    Detele命令应该很简单,除非您必须通知用户发生更新,该更新可能导致用户保留记录而不是删除记录

    您应该仔细分析如何为每种类型的实体处理每个命令(在更新的情况下,您可能会被迫为要更新的不同属性集以不同的方式处理这些命令)

    同步过程
    同步会话应开始向服务器发送带有

    • 客户端上的当前时间
    • LastSync
    通过这种方式,服务器可以计算其时间与客户端时间之间的偏移量,并将这种偏移量应用于他接收到的每个命令。此外,它还可以检查偏移量在上次同步后是否发生了变化,并选择一种策略来处理这种变化。请注意,这样,服务器将不知道客户机的时钟何时调整

    在成功同步结束时(由您决定