高复制环境的持久性策略(Google App Engine)

时间:2013-04-10 09:41:16

标签: java google-app-engine

我有这个代码thtat工作正常没有人力资源:

protected Entity createEntity(Key key, Map<String, Object> props){
    Entity result = null;
    try {
        Entity e = new Entity(key);
        Iterator it = props.entrySet().iterator();
        while (it.hasNext()) {
            Map.Entry<String, Object> entry = (Map.Entry<String, Object>) it.next();
            String propName = entry.getKey();
            Object propValue = entry.getValue(); 
            setProperty(e, propName, propValue);
        }
        key = _ds.put(e);
        if (key != null)
            result = _ds.get(key);
    } catch (EntityNotFoundException e1) {
    }
    return result;
}

这只是一个简单的方法,它的功能是在给定的Entity中创建一个新的key,否则返回NULL。这在JUnit中没有HR配置时工作正常但是当我配置它时,我总是收到一个错误,_ds.get(key)无法找到关键抛出:

EntityNotFoundException: No entity was found matching the key:

特别是在做的时候:

while(it.hasNext()){
   // stuff
   createEntity(key, map); 
   // stuff
}

我认为我的代码中的问题是它试图过早地获取实体。如果是这种情况,我怎么能处理这个问题,而不是诉诸Memcache或类似的事情。

更新

在事务中执行createEntity时,它会失败。但是,如果我在交易之外删除它,如果失败了。我需要能够在事务中运行,因为我的更高级别的API会将大量对象放在需要作为一个组的对象中。

更新

我遵循Strom的建议然而我发现了一个奇怪的副作用,没有对方法做_ds.get(key),使我的PreparedQuery countEntities失败。如果添加_ds.get(key),即使我不执行任何操作,也不保存Entity返回该获取countEntities的返回预期计数。那是为什么?

2 个答案:

答案 0 :(得分:1)

您是否尝试创建新实体,然后在同一事务中回读该实体?无法完成。

查询和获取内部事务可以查看在事务持续期间持续的数据存储的单个一致快照。 1

在事务中,所有读取都反映了事务开始时数据存储的当前一致状态。这不包括事务中的先前放置和删除。查询和获取事务内部保证在事务开始时看到数据存储的单个一致快照。 2

此一致快照视图还扩展到在事务内写入后的读取。与大多数数据库不同,查询和获取数据存储区事务不会在该事务中看到先前写入的结果。具体而言,如果在事务中修改或删除实体,则查询或获取将返回事务开始时实体的原始版本,如果该实体不存在则返回任何内容。 2

PS。你的假设很糟糕,不可能“太快”按键获取实体。按键提取非常一致。

另外,为什么还需要再次检索实体?您只需将其放入数据存储区,因此您已拥有其内容。

所以改变这一部分:

key = _ds.put(e);
    if (key != null)
        result = _ds.get(key);

对此:

key = _ds.put(e);
    if (key != null)
        result = e; // key.equals(e.getKey()) == true

答案 1 :(得分:0)

欢迎来到GAE环境,在放弃之前尝试多读一遍:

 int counter = 0;
 while (counter < NUMBER_OF_TRIES){
  try {

   //calling storage or any other non-reliable thing
   if(success) {break;} //escape away if success

   } catch(EntityNotFoundException e){
     //log exception
     counter++;
   }
 }

Google文档中的重要提示:“您可以写入同一实体组的速率限制为每秒写入实体组1次。”

来源:https://developers.google.com/appengine/docs/java/gettingstarted/usingdatastore