通过远程api更改数据存储区并不会反映在正在运行的实例上

时间:2013-05-04 21:58:20

标签: google-app-engine

我正在通过Java中的远程API更新数据存储区中的entires。

如果我在应用引擎信息中心查询更新的条目,我可以看到新版本。 但是我的servlet在更新之前运行的实例上运行并且已经提供服务读取数据存储条目仍然可以看到旧版本。

如果我手动关闭实例并启动一个新实例,它就可以很好地提供新版本。 如果我通过应用程序引擎仪表板从数据存储中删除该条目,则旧的运行实例将无法按预期读取该条目。

这似乎是以某种方式运行实例的缓存问题。看起来远程API无法告诉正在运行的实例,某些数据存储条目不能再缓存了。

我可以做些什么来改变远程API吗? 或者我应该提交错误?

注意:我没有在memcache或实例的RAM中缓存任何内容。

更新 这是我通过远程API更新新实体的方式:

DatastoreService ds = DatastoreServiceFactory.getDatastoreService();
Entity entity = new Entity("DocModel", "somekey");
entity.setProperty("html", "someProperty");
ds.put(entity);

这是使用JDO读取servlet值的方法:

PersistenceManager pm = PMF.get().getPersistenceManager();
DocModel docModel = pm.getObjectById(DocModel.class, "someKey");

这是JDO课程:

@PersistenceCapable
public class DocModel {
  @PrimaryKey
  @Persistent
  private String name;

  @Persistent
  private Text html;

  public DocModel(String path, String html) {
    this.name = path;
    this.html = new Text(html);
  }

  public String getHtml() {
    return html.getValue();
  }

  public String getPath() {
    return name;
  }
}

UPDATE2

这似乎与JDO有关。我更改了读取以使用数据存储区API,现在我看到了更新的值。使用JDO,这些更新的值将从未被看到(我几次测试了大约10分钟)。我需要杀死要传播的值的实例。

3 个答案:

答案 0 :(得分:1)

听起来像是一致性问题(如果您100%确定没有条目缓存/ PMF正在进行中)。

你确定JDO使用强一致性吗?您可以通过

强制设置
Query q = pm.newQuery(DocModel.class);
q.addExtension("datanucleus.appengine.datastoreReadConsistency", "STRONG");

Imho JDO默认使用强一致性(如jdoconfig.xml中所指定),但我要仔细检查jdoconfig.xml。

更新:强一致性不是JDO的默认值(尽管文档说的是)=>因此,您所看到的内容是有道理的,并且设置STRONG的一致性可能会解决您的问题(https://code.google.com/p/googleappengine/issues/detail?id=6326)。

答案 1 :(得分:1)

那是eventual consistency,如果你想确定在查询中看到所有最新的写入,你需要运行祖先查询

答案 2 :(得分:0)

听起来不像是一个bug,你需要自己明确地清除memcache。如果您的实例在本地内存中缓存,您还必须自己清除。这些都不是数据存储api的一部分。