我在应用引擎应用的/_ah/xmpp/presence/available/
路径中收到来自Google XMPP服务器的状态信息包。
问题是我在几毫秒内收到了很多数据包(我在myapp.appspotchat.com
后面有几个机器人)并且我必须查询数据存储区并检查用户是否已经注册了接收存在数据包。
出于某种原因,我为每个用户获得两个 可用的状态数据包,我注意到客户端的一个条目被写入数据存储区两次。我的猜测是,当第二个打包到达时,由第一个打包引发的写入在某种程度上不会被提交/合并。
所以我决定将读取和写入操作包装在事务中。现在,第二个数据包不会在数据存储上导致重复条目。但是,接收如此多的连续数据包最终会导致抛出异常(java.util.ConcurrentModificationException: too much contention on these datastore entities
)。
现在,我有四个问题:
更新:
我错了,事务没有停止第二个请求在数据存储区中找不到该条目。这是代码片段(我在应用引擎中没有任何索引):
XMPPService xmppService = XMPPServiceFactory.getXMPPService();
Presence presence = xmppService.parsePresence(req);
JID from_jid = presence.getFromJid();
DatastoreService datastore = DatastoreServiceFactory.getDatastoreService();
Key sessionKey = KeyFactory.createKey("Session", "default");
Transaction txn = datastore.beginTransaction();
Query query = new Query("Client", sessionKey).addFilter("jid", FilterOperator.EQUAL, from_jid.getId());
List<Entity> clients = datastore.prepare(query).asList(FetchOptions.Builder.withLimit(1));
if (clients.isEmpty()) {
Entity client = new Entity("Client", sessionKey);
client.setProperty("jid", from_jid.getId());
datastore.put(client);
}
txn.commit();
为什么查询返回一个空列表?
答案 0 :(得分:0)
在<threadsafe>false</threadsafe>
中配置appengine-web.xml
会强制App Engine按顺序有序地发送请求,并修复问题中提到的问题。