在App Engine中使用实体组的良好开源示例?

时间:2009-07-09 15:52:28

标签: google-app-engine entity-groups

我知道关于实体小组如何在GAE存储中工作的所有细节,但是昨天(在Palo Alto的App Engine聚会上),作为主持人解释他对实体组的使用,让我感到震惊的是我从未真正做过在我自己的GAE应用程序中使用它们,我不记得在我使用的开源GAE应用程序中看到它们。

所以,我怀疑我只是忽略了(没有注意或记住)这样的例子,因为我根本不习惯他们足以立即将“使用实体组”连接到“正在解决的那种应用程序问题” - - 我认为我应该通过研究这个目标来解决这个问题,重点关注EG使用解决的问题(即,为什么应用程序与它一起工作,但如果没有它就无法工作或不能正常工作)。

有人能为这些代码建议好的网址吗? (论文也很受欢迎,如果他们专注于应用程序级别的问题解决,但,如果像我见过的那样,他们只关注EG如何工作的细节! - 。 / p>

3 个答案:

答案 0 :(得分:22)

实体组的主要用途是提供更新交易中多个实体的方法。

如果您不必使用它们,请计算您的祝福。要么你一直在设计你的数据模型,以便不需要同时更新两个实体以保持一致,否则你确实需要它们但是你很幸运:)

想象一下,我有一个Invoice实体类型和一个LineItem实体类型。一个Invoice可以有多个与之关联的LineItem。我的Invoice实体有一个名为LastUpdated的字段。每当LineItem添加到我的发票时,我想将当前日期存储在LastUpdated字段中。

我的更新功能可能看起来像这样(伪代码)

invoice.lastUpdated = now()
lineitem = new lineitem()

invoice.put()
lineitem.put()

如果发票put()成功并且lineitem put()失败会怎样?我的发票日期将显示某些内容已更新,但实际更新(新的LineItem)不会出现。解决方案是将puts()放在事务中。

另一种解决方案是使用查询来查找最后插入的LineItem的日期,而不是将此数据存储在lastUpdated字段中。但是,每次想要知道最后一次添加lineitem时,都需要同时获取Invoice和所有LineItem,这会花费您宝贵的数据存储配额。

编辑回应海报的评论

阿。我想我理解你的困惑。以上段落确定了交易重要的原因。但是你说你仍然不关心实体组,因为你没有看到它们与交易的关系。但是,如果您正在使用db.run-in-transaction,那么您正在使用实体组,可能没有意识到它!每个事务涉及一个且仅一个实体组,并且任何给定事务只能影响属于同一组的实体。见here

  

“a中的所有数据存储区操作   交易必须对实体进行操作   在同一个实体组中。“

你在交易中做了什么样的事情?只有一个实体使用交易有很多充分的理由,默认情况下它们位于自己的实体组中。但有时您需要保持2个或更多实体同步,就像我上面的例子一样。如果Invoice和LineItem实体不在同一实体组中,则无法在db.run-in-transaction调用中将修改包装到它们中。因此,只要您想要在事务上对2个或更多实体进行操作,您首先需要确保它们位于同一组中。希望能更清楚地说明它们有用的原因。

答案 1 :(得分:2)

我已经使用了它们here。我将客户对象设置为地图标记的父级。这为每个客户创建了一个实体组,并为我提供了两个优势:

  1. 获取客户的标记要快得多,因为它们与客户对象物理存储。(在同一台服务器上,可能在同一磁盘上)

  2. 我可以在交易中更改客户的标记。我怀疑事务要求所有操作对象在同一组中的原因是因为它们存储在同一物理位置,这使得更容易实现对数据的锁定。

答案 2 :(得分:1)

我在这个简单的wiki系统中使用了它们here。页面的最新版本始终是根实体,过去的版本具有最新版本作为祖先。复制操作在事务中完成,以保持版本一致性,避免在并发时丢失版本。