当 XG(跨组)事务可以做同样的工作时,为啥要选择实体组事务?

Posted

技术标签:

【中文标题】当 XG(跨组)事务可以做同样的工作时,为啥要选择实体组事务?【英文标题】:Why should one choose an entity group transaction when XG (cross group) transaction can do the same job?当 XG(跨组)事务可以做同样的工作时,为什么要选择实体组事务? 【发布时间】:2015-06-30 13:27:19 【问题描述】:

在应用引擎数据存储设计中考虑这两种情况:

    A 是 B 的祖先。我们使用事务来更新此实体组。 A 和 B 都没有祖先。我们使用 XG 事务来更新这两个实体。

我可以在案例 2 中看到这些优势:

就像案例 1 一样,它实现了原子性。 如果我给 A 和 B 一个字符串或整数 id,考虑到它们是不同的类型,当我有另一个时,我可以查找其中一个。这相当于在案例 1 中由父母或孩子查找。 由于实体不在组中,它们不受写入吞吐量限制。

以上几点对吗?何时以及为什么应该使用案例 1 而不是案例 2?

【问题讨论】:

【参考方案1】:

XG 事务只能跨越 25 个不同的实体组,因此单个批次中可以进行的多次更改的数量是有限制的。此外,使用祖先可以让您对祖先组内的数据进行查询。

以一个简单的微博网站为例,用户可以在其中发帖和查看其他用户的帖子。您的主页显示来自所有用户的最新帖子,因此执行最终一致的查询以获取此数据是可以的(我们可以在这里容忍一些陈旧性)。但是,当用户发布帖子时,他们应该始终看到该帖子显示在他们的提要中。

如果您将每个帖子存储在其自己的 EG 中,则您对用户帖子的查询可能如下所示:SELECT * FROM Post WHERE author = $current_user。然而,这最终是一致的。因此,用户可能会发布帖子,然后不会将其显示在他们的提要中。相反,我们可以利用 EG 并让每个 Post 成为创建它的 User 的孩子。然后,我们可以查询单个用户的帖子:SELECT * FROM Post WHERE __key__ HAS ANCESTOR KEY('User', $current_user)

在这种情况下,用户将被限制为每秒创建 1 个帖子,但这与 自然边界 非常吻合——此时用户受限于输入 a 所需的时间发帖。

【讨论】:

在你的例子中,一个用户最终会有数万个帖子,使得实体组非常大。这不是问题吗?另外,在我的示例中,A 和 B 共享相同的 id 但类型不同,是否满足强一致性? 如果用户有很多帖子也没关系(显然你应该设置一个限制并使用分页来实际显示它们)。抱歉,我并不是要暗示事务不具有强一致性——Gets 和 Puts 始终是强一致性的,无论它们是否在事务中使用。

以上是关于当 XG(跨组)事务可以做同样的工作时,为啥要选择实体组事务?的主要内容,如果未能解决你的问题,请参考以下文章

当我们可以用 setter 做同样的事情时,为啥我们需要使用 builder 设计模式? [复制]

为啥在 runOnUiThread 做同样的事情时使用处理程序?

当我可以在“git init”之后对“git pull”做同样的事情时,为啥要“git clone”? [复制]

当按位运算符做同样的事情时,为啥要使用逻辑运算符?

当 Servlet、JSP 和轻量级 DAO 层可以工作时,为啥要使用 MVC 框架?

为啥 HTTP/2 多路复用虽然 tcp 做同样的事情?