我試圖實現數據存儲中的強一致性,不知道任何其他方式來處理我的需求。我有一個應用程序,用戶可以隨機連接。所以基本上在'connect'api調用中,它查詢QueueUser實體,如果它沒有找到任何實體,它將推送隊列中的主叫用戶。強化GAE上的客觀性與一致性
ofy().load().type(QueueUser.class)
.filterKey("!=", KeyFactory.createKey("QueueUser", caller.id))
.order("__key__")
.order("-time")
.limit(5)
.keys();
我明白,這將不會獲取最新的實體按鍵,爲指標可能不是最新的。所以我通過密鑰進行交流,並通過密鑰獲取每個實體。如果我得到一個非null的實體,我會嘗試刪除它。如果我成功了,我認爲這是用戶的一個匹配。這個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)。
我想知道如果我在這裏丟失了任何明顯的東西,或者有沒有更好的方法來處理這個問題。
謝謝你的回答。我知道數據存儲不適合我的要求。是的,不需要持久性存儲。我會嘗試memcache。我認爲memcache只與數據存儲一起使用,如果在memcache中找不到@cached實體,它會從數據存儲中獲取它。 – sandeepd
帶'getIdentifiable'和'putIfUntouched'的Memcache完成了這個任務。延遲大幅降低。非常感謝@stickfigure!順便說一句,在極少數情況下,兩個請求在精確的毫秒內執行'putIfUntouched',它返回'true'。 – sandeepd