繁体   English   中英

如何在Google App Engine(java)并发期间使删除的实体立即不可用?

[英]How to make deleted entities unavailable immediately during concurrency in Google App Engine (java)?

我有一个Servlet,它根据请求参数获取实体列表,并将其缓存在本地List变量中,然后立即删除它们。 删除后对对象列表执行操作。

有时,如果servlet一次获取并发请求,则两个请求都可以获取相同的实体,并且两次执行操作,这是不应该发生的。

我确认了删除时间,大约是100毫秒左右。 我需要使其他并发请求不应该读取已删除的实体。

如何在Google App Engine实例的并发期间有效地处理此问题?

我的建议是使用事务来隔离并发问题并创建幂等请求。 在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
}

不查看代码就很难分辨,但是通常观察到的行为是对共享数据结构(在您的情况下为列表)的读写访问不同步的结果。 如果是这种情况,您可以做的是同步读取/写入列表的块。 这是Java伪代码:

/**
 * Read from the cache.
 */
Data getCache(String key) {
  synchronized (this) {
     // ... Do read
  }
}

/**
 * Delete the cache.
 */
void clearCache() {
  synchronized (this) {
     // ... Do cleanup
  }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM