2014-09-11 102 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

相關問題