我正在开发一个通过其JSON API连接到Google Cloud Datastore的Google AppEngine应用程序(我正在使用PHP)。
我正在阅读Google提供的所有文档,我仍然有疑问:
在关于Transactions的文档中,有以下提及:“事务必须对属于有限数量(5)的实体组的实体进行操作”(顺便说一下,我们可以找到以下几行: “事务中的所有数据存储区操作都可以在最多25个实体组上运行”。 我不确定什么是实体组。假设我有一个对象Country,它只能通过其种类(COUNTRY)和数据存储区的自动受影响的密钥ID来识别。所以没有祖先路径,等级关系等等......所有国家实体只计算1个实体组吗?或者每个国家都计算一个?
对于Country实体类型,我需要一个增量唯一ID(如SQL AUTOINCREMENT)。它必须是绝对独特的,没有差距。此外,这种对象不会创建超过几分钟/分钟,因此不需要处理争用和分片。我正在考虑使用一个独特的计数器来反映自动增量并在事务中使用它。以下代码模式是否正常?:
Starting transaction, getting the counter, commit the creation of the Country along with the update of the counter. Rollback the transaction if the commit fails.
这种模式是否会阻止2个相同ID的影响?您能否确认我,如果2个进程同时获得计数器(因此值相同),则第一个提交将使另一个失败(因此它将能够重新启动并获得新的计数器值)? / p>
documentation还提到:“如果您的应用程序在尝试提交事务时收到异常,则不一定意味着事务已失败。可能会收到异常或错误消息即使交易已经提交并最终将成功应用“!?我们该怎么处理这个案子?如果在创建我的国家时出现这种情况(问题#2),我的自动增量ID就会出现问题,不是!?
由于数据存储区需要事务的所有写入操作仅在一次调用中完成。并且由于事务确保将执行所有事务或不执行任何事务,为什么我们必须进行回滚?
仅限于1个写入/秒的实体(因此通过其类型及其关键路径定义的东西)而不是整个实体组(只有当我确定什么时,我才会放心确切地说是一个实体组;-)问题#1)
我在这里停下来不做一个巨大的帖子。在得到这些问题的答案后,我可能会回复其他(或改进的)问题; - )
感谢您的帮助。
[更新]国家/地区仅用作示例类对象。
答案 0 :(得分:3)
不,('Country', 123123)
和('Country', 679621)
不在同一个实体组中。但('Country', 123123, 'City', '1')
和('Country', 123123, 'City', '2')
位于同一实体组中。具有相同祖先的实体属于同一组。
对于像国家这样的事情使用自动增量听起来真是个坏主意。只需根据国家/地区的名称生成ID。
来自同一段:
尽可能构建数据存储区事务,以便在同一个事务多次应用时,最终结果不会受到影响。
在内部数据存储区API(如db或ndb)中,您不必担心回滚,它会自动发生。
每个整个实体组每秒写约 1次,这就是为什么你需要让组尽可能小。