【问题标题】:datastore transaction restrictions数据存储事务限制
【发布时间】:2010-10-24 15:11:07
【问题描述】:

在我的 google app 应用程序中,每当用户购买多个合约时,都会执行这些事件(为清晰起见进行了简化):

  • user.cash 减少
  • user.contracts 增加了个数
  • contracts.current_price 已更新。
  • market.no_of_transactions 增加 1。

在 rdms 中,这些将被放置在同一个事务中。我认为谷歌数据存储不允许多个模型的实体在同一个事务中。

解决这个问题的正确方法是什么?如何确保如果写入失败,则所有先前的写入都回滚?

edit:我显然错过了实体组。现在,我将不胜感激有关如何使用它们的更多信息。需要澄清的另一点是谷歌说“仅在交易需要时使用实体组。对于实体之间的其他关系,请使用 ReferenceProperty 属性和键值,它们可以在查询中使用”。这是否意味着我必须同时定义参考属性(因为我需要查询它们)和父子关系(用于事务)?

编辑 2:最后,如果创建实体以在 2 个父级之间建立 n 对 n 关系,我如何为一个实体定义两个父级?

【问题讨论】:

    标签: python google-app-engine transactions google-cloud-datastore


    【解决方案1】:

    shanyu,您提到了分布式事务层,它允许您在单个事务中跨任意多个实体组进行操作。它实际上 has been released,它只是没有被大声宣传。它是由 daniel wilkerson 和 erick armbrust 设计和编写的,我也提供了一些咨询。 dan 在this talk 中描述了它。

    尼克约翰逊也描述了 how to do "transfer" type operations across entity groups,和你描述的差不多。它不像木薯粉那样通用,但它更简单,重量更轻。

    有一个相关的内置功能transactional tasks,可让您将任务添加到数据存储事务中的队列中,这样只有在事务成功提交时才会添加它。然后,该任务可以执行更多数据存储操作,包括不同实体组上的事务。它不如 dan 和 erick 的解决方案强大,但它确实为您提供了跨实体组的最终一致性保证,这对于许多用例来说已经足够了,而且没有额外的开销。

    回答您的问题:1) 您不需要同时使用引用属性和父/子关系(即实体组)。该准则仅意味着实体组限制数据存储写入吞吐量,因为写入是按实体组序列化的。如果您正在考虑将数据构建到实体组中仅用于祖先查询,您应该意识到这一点。

    2) 一个实体不能有多个父级。如果要建模多对多关系,通常应该使用引用属性(即键)的 ListProperty。详情请参阅this article 和this talk。

    【讨论】:

    • @systempuntoout 我的意思是你会在任务处理程序中写入不同的实体组,而不是在原始事务中。
    • 误会,我没用的评论会在几分钟内消失:)。
    【解决方案2】:

    让我添加来自Datastore documentation的引用:

    实体组的一个好的经验法则是,它们应该是 单个用户价值的大小 数据或更小。

    您可以创建一个伪根实体并将所有内容放在此之下。然后,您执行事务中的所有内容。

    【讨论】:

      【解决方案3】:

      经过一番研究,我发现在一些谷歌人的帮助下,在用户空间开发了一个分布式事务层,它提供了一个解决单一实体组限制的解决方案。但到目前为止,它还没有发布,只在java中可用。

      【讨论】:

        猜你喜欢
        • 2022-01-23
        • 2021-12-02
        • 2015-09-20
        • 1970-01-01
        • 1970-01-01
        • 2013-01-02
        • 1970-01-01
        • 2011-09-05
        • 2012-03-09
        相关资源
        最近更新 更多