代码之家  ›  专栏  ›  技术社区  ›  Alex Martelli

在应用程序引擎中使用实体组的良好开源示例?[关闭]

  •  21
  • Alex Martelli  · 技术社区  · 16 年前

    我知道所有关于实体组如何在GAE存储中工作的细节,但是昨天(在帕洛阿尔托的应用引擎会议上),作为一个演示者解释他对实体组的使用时,让我吃惊的是,我从未真正在自己的GAE应用中使用过它们,我不记得在我使用的开源GAE应用中看到过它们。

    因此,我怀疑我只是忽略了(没有注意到或记住)这些例子,因为我对它们的习惯不够,不能立即将“实体组的使用”与“正在解决的应用程序问题的类型”联系起来——我认为我应该纠正这一点,通过研究这些源代码并牢记这一目标,重点关注EG使用的是解决什么问题。ng(也就是说,为什么应用程序与它一起工作,但是没有它就不能工作或不能很好地工作)。

    有人能给这样的代码推荐一个好的网址吗?(如果论文专注于应用程序级的问题解决,也会受到欢迎,但是 如果像我见过的大多数人一样,他们只关注EGS如何工作的细节!-)

    3 回复  |  直到 15 年前
        1
  •  22
  •   Peter Recore    16 年前

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

    如果你不必使用它们,那么就数数你的祝福吧。要么你一直在设计你的数据模型,以至于不需要同时更新两个实体来保持一致,要么你确实需要它们,但你已经幸运了:)

    假设我有一个发票实体类型和一个行项目实体类型。一张发票可以有多个与之关联的行项目。我的发票实体有一个名为lastupdated的字段。每次将行项目添加到发票时,我都希望将当前日期存储在LastUpdated字段中。

    我的更新函数可能如下(伪代码)

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

    如果invoice put()成功而lineitem put()失败,会发生什么?我的发票日期将显示某些内容已更新,但实际更新(新的行项目)将不存在。解决方案是将两个puts()都放入事务中。

    另一种解决方案是使用查询来查找最后插入的行项目的日期,而不是将此数据存储在最后更新的字段中。但这将涉及每次您想知道最后一次添加行项目时同时获取发票和所有行项目,这会使您损失宝贵的数据存储配额。

    编辑以回应海报的评论

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

    “中的所有数据存储操作 事务必须在实体上操作 在同一实体组中”。

    你在交易中做什么?只有一个实体可以使用事务,这是有充分的理由的,默认情况下,该实体在其自己的实体组中。但有时您需要保持两个或多个实体同步,就像在上面的示例中一样。如果发票和行项目实体不在同一实体组中,则无法在db.run-in-transaction调用中包装对它们所做的修改。因此,任何时候,如果你想在两个或两个以上的实体上进行交易,你首先需要确保它们在同一个集团中。希望能更清楚地说明为什么它们有用。

        2
  •  2
  •   Sudhir Jonathan    16 年前

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

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

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

        3
  •  1
  •   moraes    15 年前

    我已经用过了 here 在这个简单的wiki系统中。页面的最新版本始终是根实体,以前的版本将最新版本作为祖先。复制操作在事务中完成,以保持版本一致性,并避免在并发情况下丢失版本。

    推荐文章