【发布时间】:2017-05-27 13:46:09
【问题描述】:
我正在尝试在数据存储中实现强一致性,不知道有什么其他方法可以满足我的要求。我有一个用户随机连接的应用程序。所以基本上在 'connect' api 调用中,它会查询 QueueUser 实体,如果没有找到,它将把调用用户推送到队列中。
ofy().load().type(QueueUser.class)
.filterKey("!=", KeyFactory.createKey("QueueUser", caller.id))
.order("__key__")
.order("-time")
.limit(5)
.keys();
我知道这不会获取最新的实体键,因为索引可能不是最新的。所以我通过键进行交互并通过它的键获取每个实体。如果我得到一个非空实体,我会尝试删除它。如果我成功了,我认为这是用户的匹配。这个 get-by-key 和 delete() 在 Transaction 中。
while(keyIterator.hasNext()) {
QueueUser queueUser = null;
try {
final Key<QueueUser> key = keyIterator.next();
queueUser = ofy().transactNew(1, new Work<QueueUser>() {
public QueueUser run() {
QueueUser queueUser = ofy().load().key(key).now();
if(queueUser == null) {
logger.log(Level.WARNING, "queue user was already deleted");
return null;
}
else
ofy().delete().key(key).now();
return queueUser;
}
});
} catch (ConcurrentModificationException e) {
logger.log(Level.WARNING, "exception while deleting queue user. err: " + e.getMessage());
}
if (queueUser != null) {
// we have a match here
// delete calling user from the queue if it's there
ofy().delete().entity(new QueueUser(caller.id, null, null, null, null, null, null, null, null)).now();
break;
}
}
这在大多数情况下都有效,但有时用户会被推到队列中而没有迅速接听。请求延迟最长可达 15 秒。查询返回很多实体,但大多数都被删除了,有些被对等请求删除(预期的 ConcurrentModificationException)。
我想知道我是否在这里遗漏了任何明显的东西,或者有没有更好的方法来处理这个问题。
【问题讨论】:
标签: java google-app-engine google-cloud-datastore objectify