2014-09-11 703 views
0

Google AppEngine中的get()在什么情况下会抛出EntityNotFoundExceptionEntityNotFoundException的可能原因

是否真的只有如果在请求时请求的密钥在数据存储区中不存在,或者由于呼叫过程中的其他问题也可能发生,例如超时?

换句话说,如果我开始一个新的事务并在该交易中get()抛出EntityNotFoundException,可我是100%肯定的是,在同一事务中put()永远覆盖一些已经存在的项目,那不知何故错过了get()

添加一些代码:

private Entity getOrCreate(Key key, String initialData) { 
    DatastoreService datastore = DatastoreServiceFactory.getDatastoreService(); 
    Transaction txn = datastore.beginTransaction(); 
    try { 
     Entity result; 
     try { 
      // Try to read existing entity 
      result = datastore.get(key); 
     } catch (EntityNotFoundException e) { 
      // If entity is not found, create and put a new one 
      result = new Entity(key); 
      result.setProperty("data", initialData); 
      datastore.put(result); // Could this EVER overwrite an existing entity? 
     } 
     txn.commit(); 
     return result; 
    } finally { 
     if (txn.isActive()) txn.rollback(); 
    } 
} 

难道这代码不断覆盖由事故现有的实体由于一些机制,导致EntityNotFoundException 其他比这个实体真的不存在?

回答

1

当您正在进行交易时,您的整个实体组将被交易冻结,直到您提交。因此,就你的情况而言,如果实体组被锁定,那么在获取和放弃之间没有人“推”他自己的实体的真实机会。

我个人可以用“entityNotFound”看到的唯一问题与最终的一致性有关。例如,如果实例已创建但尚未完全一致,则某些get()查询可能会返回“EntityNotFound”。我会使用强一致的查询(如get_by_id)来确保数据存储的一致性。

您应该收到“EntityNotFound”错误的唯一时间是来自未被捕获的实体。在这种情况下,要么是实体不存在,要么一致性不强。使用强一致的查询(祖先查询或get_by_id)可以解决这个问题。

看着this可能会帮助你重组你的模型:)

+0

@MarkusA。让现在更有意义:)。检查我编辑的答案,可能会帮助你^^ – Patrice 2014-09-11 17:36:55

+0

:)是的!谢谢! :)我删除了我的评论,而是编辑了一些我的问题。这就是我最担心的一个例子,即“最终一致性”案例。不幸的是,我不太清楚“get_by_id”是什么意思。你的意思是一个特定的键而不是查询的实际“get()”? – 2014-09-11 17:42:39

+0

但基本上你是说没有其他错误机制(读取超时或其他)会导致错误? – 2014-09-11 17:49:22

相关问题