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

时间:2017-05-18 06:32:13

标签: java google-app-engine gwt

如何为实体分配唯一编号。 唯一的数字范围将由用户定义,例如1000000001所以接下来 数字将是1000000002,依此类推。

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

我在保存任何实体时正在做的事情。我读取了我的号码范围实体并选择了那里更新的最后一个号码并将该号码增加1并将该号码分配给我要保存的实体。之后,我将我的号码范围实体保存为更新的号码。

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

1 个答案:

答案 0 :(得分:0)

如果实体number引用了实体的密钥名称/标识符,则防止将相同的号码分配给不同记录的唯一方法是预先保留它们。来自Assigning identifiers

  

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

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

  • 阅读您存储最后指定值的last assigned实体
  • 递增值以获取当前数字
  • 将当前号码保存在last assigned实体
  • 如上所述分配新标识符(如果适用)
  • 使用当前号码
  • 创建新实体

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

使用这些关键名称/标识符的增量值或仅仅属性可能会导致“热点”和“热门平板电脑”变得毫无价值。数据存储区可伸缩性问题,影响读/写/索引操作的性能。来自High read/write rates to a narrow key range

  

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

     

...

     

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

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

...

     
      
  • 如果以高速率创建新实体并且单调增加索引属性(如a),您也会看到此问题   timestamp,因为这些属性是索引中行的键   Bigtable中的表格。
  •