【问题标题】:DataStore with Objectify - Load entities/keys without specifying parent带有 Objectify 的 DataStore - 加载实体/键而不指定父级
【发布时间】:2016-06-16 12:06:44
【问题描述】:

在一个事务中,我需要加载多个实体(十分之一)并且这些实体被分配给一个父实体,因此它们被视为一个实体组(否则我们无法在单个事务中加载这些实体) ,效果很好,但是每次我们需要查询这些实体时,父实体都会被加载

ofy().load().type(clazz).parent(parent).ids(keys);

如果我们想在没有加载父实体的情况下加载实体,那么这应该可以工作并加载实体,但它没有

ofy().load().type(clazz).ids(keys);

这背后的原因是,如果两个或多个线程确实调用加载相同/不同的条目(但相同的父项),则会导致父实体的负载过多“java.util.ConcurrentModificationException:这些数据存储实体的争用过多. 请再试一次。”

请指教

【问题讨论】:

    标签: java google-app-engine google-cloud-datastore objectify


    【解决方案1】:

    你的ofy().load().type(clazz).ids(keys) 没有显示工作的原因是你没有指定父键 - 这相当于寻找 root的键> 实体(即没有父级的实体),这显然会产生不同的结果。

    父键(实际上是整个祖先)嵌入在子实体键中,请参阅Ancestor paths

    不幸的是,您必须指定父级 - 父级(实际上是整个实体组,尤其是写入操作)上的“负载”是为在其中工作的优势付出的代价同一个实体组。

    【讨论】:

    • 这意味着加载 X 实体 keys 屈服于加载 X 父 entity ,这意味着在事务中,您根本无法加载 1K keys 这完全没有意义,我不确定它是否正确..
    • 加载实体或其键并不意味着父实体或其键也已加载(父实体甚至可能不存在,请参阅stackoverflow.com/a/37283449/4495081)。
    • 争用是访问同一个实体组引起的,而不是组实体/键本身的数量。
    • 好吧,让我重写我的问题.. 如果我们加载 X 实体,那么父节点会被加载 X 次,并假设只有一个线程正在访问 不同实体但同一个父实体,那么这会导致对同一实体的访问过多 -
    【解决方案2】:

    这个问题的根源在于对事务和实体组在数据存储区中的工作方式存在根本性的误解。

    官方文档很方便:

    https://cloud.google.com/appengine/docs/java/datastore/transactions#Java_Entity_groups

    前段时间写过,可能比较容易理解:

    https://github.com/objectify/objectify/wiki/Concepts

    请记住,这与加载父实体无关。这是关于在交易中招募实体组。如果您触及该 EG 中的任何实体(即具有公共父键的任何实体),则您已将整个 EG 纳入事务。

    【讨论】:

    • 所以,问题又来了,如果我们加载 X 个实体,那么父级会被加载 X 次,并假设只有一个线程正在访问不同的实体但相同的父级,那么这也是原因对同一实体的多次访问 - 父级(发生异常),如何更好地处理这个?
    • 您需要仔细平衡您的需求,一方面是强一致性,另一方面是事务吞吐量。正确的答案几乎总是在没有强一致性的情况下将您的实体放在单独的实体组中,但这实际上取决于您的应用程序。
    • 来自https://github.com/objectify/objectify/wiki/Concepts#entity-groups "就此而言,您可以使用指向不存在实体的父键(或任何其他键作为成员字段)创建子实体!父仅重要在于它定义实体组;如果您不需要跨多个实体的事务,您可能希望使用正常的非父键关系——即使实体具有概念上的父子关系。”这对我有帮助吗?
    猜你喜欢
    • 2015-03-10
    • 2023-03-27
    • 2013-10-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多