如何在 GAE 中为整体分配自定义定义唯一编号?



如何为实体分配唯一编号。 唯一编号范围将由用户定义,例如1000000001,因此下一个 数字将1000000002,依此类推。

目前,我正在维护一个单独的实体来管理其他实体的编号范围。

我现在在拯救任何实体时正在做什么。我读取了我的号码范围实体并选择在那里更新的最后一个数字,并将该数字增加 1 并将该号码分配给要保存的实体。之后,我将使用更新的数字保存我的数字范围实体。

问题:由于它是一个Web应用程序,因此多个用户同时访问它。如果多个用户同时保存同一实体,则会为多个记录分配相同的唯一编号。 如何克服这个问题?

如果您通过实体number引用实体的键名称/标识符,则防止将相同编号分配给不同记录的唯一方法是事先保留它们。从分配标识符:

注意:高级应用程序有时可能希望分配,而不是使用键名称字符串或自动生成数字 ID 他们自己的数字 ID 手动到他们创建的实体。请注意, 但是,没有什么可以阻止云数据存储 将一个手动数字 ID 分配给另一个实体。唯一的 避免此类冲突的方法是让您的应用程序获得一个块 具有DatastoreService.allocateIds()方法的 ID 或AsyncDatastoreService.allocateIds().云数据存储的 自动 ID 生成器将跟踪已分配的 ID 使用这些方法,并将避免将它们重用于另一个实体,因此 您可以安全地使用此类 ID,而不会发生冲突。

无论使用数字作为键名/标识符还是仅用作属性值,为了防止多个同时请求分配相同的数字,您需要在单个事务中执行所有这些操作:

  • 读取存储上次分配值的last assigned实体
  • 递增该值以获取当前数字
  • 将当前数字保存在last assigned实体中
  • 分配上述新标识符(如果适用)
  • 使用当前编号创建新实体

您的代码应准备好重试整个事务,因为当多个请求尝试同时执行此操作时,它将失败 - 只有一个(最多)会成功更新last assigned实体。

对键名/标识符或仅属性使用此类递增值可能会导致"热平板电脑"数据存储可扩展性问题,从而影响读/写/索引操作的性能,这是毫无价值的。从高读/写速率到窄键范围:

如果您使用的是云数据存储,则由于过热,写入速度可能会很慢 平板电脑,如果您的写入速率突然增加到一个小 超出单个平板电脑服务器容量的密钥范围。 Bigtable最终将拆分密钥空间以支持高负载。

默认情况下,云数据存储使用分散的密钥分配密钥 算法。因此,您通常不会在云上遇到热点 数据存储写入(如果使用高写入速率创建新实体) 默认 ID 分配策略。有一些极端情况 你可以遇到这个问题:

  • 如果您以非常高的速率创建新实体,并且您正在分配自己的 ID,这些 ID 单调递增。

  • 如果您使用单调递增的索引属性(如 时间戳,因为这些属性是索引中行的键 大表中的表。

最新更新