C#并发应用程序-唯一自定义生成的ID

C#并发应用程序-唯一自定义生成的ID,c#,sql-server,entity-framework,C#,Sql Server,Entity Framework,我正在开发一个ASP.Net应用程序,它本身并不是一个真正的分布式应用程序,但在某个时候,它的所有数据都会同步到主节点 为了能够将来自不同节点的数据存储在一个唯一的表上 在没有ID冲突的情况下,采取的方法是: I.不使用自动生成的ID 二,。行Id将由NodeId+NextRowtId NextRowId由以下内容生成: 从一个特定节点中选择最高id 将其分为两部分,第一部分是节点ID,第二部分是LastDocumentId 递增LastDocumentId 将节点ID与递增的LastDoc

我正在开发一个ASP.Net应用程序,它本身并不是一个真正的分布式应用程序,但在某个时候,它的所有数据都会同步到主节点

为了能够将来自不同节点的数据存储在一个唯一的表上 在没有ID冲突的情况下,采取的方法是:

  • I.不使用自动生成的ID
  • 二,。行Id将由NodeId+NextRowtId
NextRowId由以下内容生成:

  • 从一个特定节点中选择最高id
  • 将其分为两部分,第一部分是节点ID,第二部分是LastDocumentId
  • 递增LastDocumentId
  • 节点ID与递增的LastDocumentId
  • 例如
    Id=20099,分为(NodeId=200,LastDocumentId=99)

    LastDocumentId+1=100

    NextRowId=200100

    这在理论上非常有效,或者如果请求是按顺序处理的话。但是,如果同时处理多个请求,它们通常会生成相同的id

    因此,在实践中,如果多个用户同时尝试更新同一个表,则会出现ID冲突

    我已经了解了为分布式系统生成唯一ID的最佳实践。然而,在这个时候,它们都不是一个可行的选择,因为它们需要重新思考整个体系结构和大量的重构。两者都需要时间,管理层不允许我花时间

    那么,还有什么其他方法可以确保生成的ID是唯一的,或者以顺序方式处理请求?所有这些,理想情况下不必重新构造应用程序或造成性能瓶颈。

    在关键列上创建一个。如果您碰巧插入了相同的id两次,请捕获异常并重新生成您的id

    你可能想用它来代替

    也就是说,如果您需要知道数据与哪个节点关联,您应该根据它对数据库进行建模:有两列
    NodeId
    DocumentId
    。您还可以在多个列上方生成唯一约束。

    在键列上创建一个。如果您碰巧插入了相同的id两次,请捕获异常并重新生成您的id

    你可能想用它来代替


    也就是说,如果您需要知道数据与哪个节点关联,您应该根据它对数据库进行建模:有两列
    NodeId
    DocumentId
    。您还可以在多个列上方生成唯一约束。

    您是否要求这些ID是连续的,没有间隙?如果不是-只使用sql server sequence。您是否要求这些ID是连续的,没有间隙?如果不是的话,就使用sql server序列。我建议不要使用GUI。最好使用或只是
    identity
    。然而,我不知道EF是否支持序列。我建议使用GUI。每个节点都可以为其拥有的每个记录生成一个GUID,这是安全的,因为标识符不会与系统中的任何其他内容冲突。即使到主节点的数据同步在实体创建后很长时间内发生,节点不必担心主节点拒绝生成的id。它还消除了在创建任何子节点之前,在创建每个记录之后从数据库中读回
    标识整数的需要。@Christian Gollhardt非常感谢您的回答。我们确实使用了唯一约束,但是我们没有使用catch-resave方法,而是按照JohnyL的建议使用了序列。这将需要更多的工作,但它可以确保每个DocumentId都是唯一的,并消除了合并的风险。@JohnyL我没有找到一种直接的方法来使用EF序列。但如果您使用EF raw查询,您可以使用它。@Ferox是的,这将是最后的手段,但最好将它“放在盒子里”:)我建议不要使用GUI。最好使用或只是
    identity
    。然而,我不知道EF是否支持序列。我建议使用GUI。每个节点都可以为其拥有的每个记录生成一个GUID,这是安全的,因为标识符不会与系统中的任何其他内容冲突。即使到主节点的数据同步在实体创建后很长时间内发生,节点不必担心主节点拒绝生成的id。它还消除了在创建任何子节点之前,在创建每个记录之后从数据库中读回
    标识整数的需要。@Christian Gollhardt非常感谢您的回答。我们确实使用了唯一约束,但是我们没有使用catch-resave方法,而是按照JohnyL的建议使用了序列。这将需要更多的工作,但它可以确保每个DocumentId都是唯一的,并消除了合并的风险。@JohnyL我没有找到一种直接的方法来使用EF序列。但如果您使用EF raw查询,您可以使用它。@Ferox是的,这将是最后的手段,但最好将它放在“框中”: