gpt4 book ai didi

java - JDO - 保留两个具有相同 key 的实体

转载 作者:行者123 更新时间:2023-12-02 00:04:52 25 4
gpt4 key购买 nike

我正在开发一个 AppEngine 项目,并且在 AppEngine 数据存储之上使用 JDO 来实现持久性。我有一个实体,它使用编码字符串作为键,还使用应用程序生成的键名(也是一个字符串)。我这样做是因为我的应用程序会经常从野外获取数据(可能会获取相同的数据)并尝试保留它们。为了避免持久化本质上包含相同数据的多个实体,我决定对这些数据的一些属性进行哈希处理,以获得一致的键名(由于实体关系而不是直接操作键)。现在的问题是,每当我计算散列(键名)并尝试存储实体时,如果它已经存在于数据存储中,则数据存储(或 JDO 或罪魁祸首是谁)会默默地覆盖数据存储中实体的属性,而不会引发任何异常。这对应用程序有严重影响,因为它覆盖了实体(我们用于排序)的时间戳(字段)。我怎样才能最好地解决这个问题?

最佳答案

您需要执行 get-before-set(检查并设置或 CAS)。

CAS 是并发的基本租户,也是并行计算不可避免的祸害。

无论如何,获取比套装便宜得多,因此实际上可能会省钱。

不要盲目写入数据存储,而是先检索;如果实体不存在,则捕获异常并仅放置实体。如果确实存在,请在保存之前进行深入比较。如果没有任何改变,就不要坚持它(并节省成本)。如果它已更改,请随意选择合并策略。维护过时修订的一种(有点丑陋)方法是将先前的实体存储为更新实体中的字段(可能不适用于许多修订)。

但是,在这种情况下,您必须在设置之前获取。如果您不希望有很多重复项并且想要真正简单,您可以先执行一个存在查询...这是对您要使用的键执行仅键计数查询(成本比完整获取少 7 倍) )。如果 (count() == 0) then put() else getAndMaybePut() fi

计数查询语法可能看起来很慢,但从我的基准来看,它是判断实体是否存在的最快(也是最便宜)的方法:

public boolean exists(Key key){
Query q;
if (key.getParent() == null)
q = new Query(key.getKind());
else
q = new Query(key.getKind(), key.getParent());
q.setKeysOnly();
q.setFilter(new FilterPredicate(
Entity.KEY_RESERVED_PROPERTY, FilterOperator.EQUAL, key));
return 1 == DatastoreServiceFactory.getDatastoreService().prepare(q)
.countEntities(FetchOptions.Builder.withLimit(1));
}

关于java - JDO - 保留两个具有相同 key 的实体,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14086900/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com