2013-04-10 59 views
0

我有這樣的代碼thtat只是正常的W/O HR:持久性策略高複製環境(谷歌應用程序引擎)

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出aa給出key,否則返回NULL。這沒有JUnit的人力資源配置工作正常,但是當我配置它,我總是得到一個錯誤,其中_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),使我PreparedQuerycountEntities失敗。如果增加一個_ds.get(key)即使我什麼都不做或者保存Entity返回從那個得到countEntities返回預期的計數。這是爲什麼?

回答

1

您嘗試創建一個新的實體,然後在同一事務中讀回該實體?無法完成。

查詢和獲取內部事務可以查看數據存儲的單個一致快照,該快照在事務持續期間持續存在。 1

在事務中,所有讀取都反映事務開始時數據存儲的當前一致狀態。這不包括交易中的先前的放入和刪除。在事務內部進行查詢和保證會在事務開始時看到數據存儲的單個一致快照。 2

這種一致的快照視圖還延伸到事務內寫入後的讀取。與大多數數據庫不同的是,查詢並進入數據存儲事務內部並沒有看到該事務內先前寫入的結果。具體而言,如果實體在事務中被修改或刪除,則查詢或獲取會在交易開始時返回實體的原始版本,如果實體不存在,則返回該實體的原始版本。 2

PS。你的假設是worng,「太快」就不可能通過密鑰獲取實體。通過密鑰獲取是非常一致的。

另外,爲什麼你需要再次檢索實體呢?你只需要將它放在數據存儲區中,所以你已經擁有了它的內容。

因此改變這一部分:

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 
+0

你的建議工作,它對我的​​應用程序有一個奇怪的副作用 – xybrek 2013-04-10 12:26:59

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++; 
    } 
} 

重要提示從谷歌文檔:「上,你可以寫信給同一個實體組的速率被限制1每秒寫入實體組。「

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

+0

這是做數據存儲看跌,但它也有放申請再拿到? – 2013-04-10 10:23:43

+0

我想知道1秒,NUMBER_OF_TRIES的最佳值是什麼 – 2013-04-10 10:27:35

+0

這是我在執行此操作時得到的結果:IllegalStateException:事務處於COMMITTED狀態。這種狀態沒有合法的轉變。 – xybrek 2013-04-10 10:29:50