我有一个servlet,它根据请求参数获取实体列表,并在立即删除之前将它们缓存在本地List变量中。删除后使用对象列表执行操作。
有时,如果servlet立即获得并发请求,则两个请求都能够获得相同的实体,并且执行两次不会发生的操作。
我验证了删除时间,大约是100毫秒左右。我需要让其他并发请求不能读取已删除的实体。
如何在Google App Engine实例的并发过程中有效处理此问题?
答案 0 :(得分:1)
我的建议是使用事务来隔离并发问题并创建 一个幂等的要求。在Java中,类似这样:
DatastoreService datastore = DatastoreServiceFactory.getDatastoreService();
PreparedQuery pq = createYourQuery(datastore); // remember to setKeysOnly()
for (Entity entity : pq.asIterable()) {
try {
Transaction tx = datastore.beginTransaction();
try {
datastore.get(entity.getKey());
} catch (EntityNotFoundException e) {
continue;
}
datastore.delete(entity.getKey());
tx.commit();
} catch (ConcurrentModificationException e) {
continue;
}
// execute your extra stuff
}
答案 1 :(得分:-1)
在不查看代码的情况下很难分辨,但通常您观察到的行为是对共享数据结构的不同步读/写访问的结果,在您的情况下是一个列表。如果是这种情况,您可能要做的是同步读/写列表的块。这是Java伪代码:
/**
* Read from the cache.
*/
Data getCache(String key) {
synchronized (this) {
// ... Do read
}
}
/**
* Delete the cache.
*/
void clearCache() {
synchronized (this) {
// ... Do cleanup
}
}