1

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

如果我在应用引擎仪表板中查询更新的条目,我可以看到新版本。但是我的 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;
  }
}

更新2

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

4

3 回答 3

1

这是最终的一致性,如果您想确保在查询中看到所有最新写入,则需要运行祖先查询

于 2013-05-06T12:16:55.173 回答
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)。

于 2013-05-06T11:14:21.290 回答
0

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

于 2013-05-05T01:05:58.033 回答