2012-10-02 44 views
0

全部, 我有一段代碼在數據存儲中寫入某些內容,並在撥打電話以檢索剛寫入數據存儲的數據後立即生效。我的第二個電話總是失敗!但是,如果我再次打電話,它工作正常,並找到數據! 它真的有線!代碼在1.7.1上運行正常,我在升級到1.7.2後開始發生(不能100%確定,因爲我同時還做了其他一些更改,但我想我也提到了它) 。 這裏是我的代碼寫入數據:谷歌應用引擎JDO延遲數據持久性

PersistenceManager pm = PMF.get().getPersistenceManager(); 
    pm.evictAll(); 
    Key userKey = KeyFactory.createKey(User.class.getSimpleName(), request.getUsername()); 
    try { 
     User user = pm.getObjectById(User.class,userKey); 
     if (!user.getPassword().equals(request.getPassword())){ 
      ret.setCode(ResultInfo.WRONG_PASSWORD); 
     }else{ 
      ret.setCode(ResultInfo.FINE); 
      UUID sid = UUID.randomUUID(); 
      ret.setCredit(user.getCredit()); 
      ret.setSid(sid.toString()); 
      ret.setUsername(user.getUsername()); 
      ret.setName(user.getName()); 
      user.setSid(sid.toString()); 
      user.setLastLogin(new Date()); 
     } 
    } catch (Exception e) { 
     ret.setCode(ResultInfo.USER_NOT_FOUND); 
    }finally{ 
     pm.flush(); 
     pm.close(); 
    } 

,這是讀取數據的代碼:

PersistenceManager pm = PMF.get().getPersistenceManager(); 
    pm.evictAll(); 
    try { 
      User user = getUserForSession(pm, sid); 
     if (user==null){ 
      ret.setCode(ResultInfo.SESSION_NOT_FOUND);    
     }else{ 
      ret.setCode(ResultInfo.FINE); 
      ret.setCredit(user.getCredit()); 
      ret.setSid(sid.toString()); 
      ret.setUsername(user.getUsername()); 
      ret.setName(user.getName()); 
      if (user.getGid()!=null){ 
       Game game = getGameByGameId(pm, user.getGid()); 
       ret.populateGameResult(user,game); 
      } 
     } 
    } catch (Exception e) { 
     ret.setCode(ResultInfo.USER_NOT_FOUND); 
    } finally{ 
     pm.flush(); 
     pm.close(); 
    } 

getUserForSession簡單地使用下面的代碼來獲取用戶:

static public User getUserForSession(PersistenceManager pm,String sid){ 
Query q = pm.newQuery(User.class); 
q.setFilter("sid == sidParam"); 
q.declareParameters("String sidParam"); 
    try { 
     List<User> users = (List<User>) q.execute(sid); 
     if (users.size()!=1){ 
      return null; 
     }else{ 
      return users.get(0); 
     } 
    } catch (Exception e) { 
     return null; 
    } finally { 
    } 

} 

當我在這個函數中調試時,列表的大小在第一次調用時爲零,在下一次調用時爲1,參數完全相同! 因爲我在第一次通話中總是收到SESSION_NOT_FOUND錯誤,在第二次通話中我收到了我想要的數據!

第二個代碼段被Ajax調用,所以現在我已經改變了我的代碼來檢查錯誤並再次調用!我不喜歡它,我想知道如何才能解決這個問題。這裏是我的Ajax代碼:

function fetchUserInfo(){ 
    var sid = getCookie("sid"); 
    var urlStr = BURL + '/game/' + sid + "/gameInfo"; 
    $.ajax({ 
     type:'POST', 
   url: urlStr, 
   dataType: 'json', 
   data: null, 
     contentType: "application/json; charset=utf-8", 
   success: function(data) { 
      console.debug(data); 
      if (data.code == "OK"){ 
       try{ 
        $("#client_name").html(data.name); 
        $("#client_credit").html(data.credit); 
       }catch(e){ 
       } 
      }else{ 
       fetchUserInfo(); 
      } 
     }, 
     error: function(data){ 
      alert("Error"); 
     }    
    }); 

    } 

任何幫助/指針表示讚賞

阿米爾

+0

我幾乎可以肯定這個問題與HRD相關,因爲當我將它關閉時,所有工作都很好,但是我真的想要利用HRD,但也迫使數據準備好在數據持久。 –

+0

感謝您的好評兄弟!我知道我有什麼,你是告訴我我錯過了什麼:) –

+0

你是什麼意思「關閉HDR」?你在談論開發服務器嗎?它的行爲與「真實」數據存儲的行爲不同。 –

回答

1

當寫入HRD,有持久化數據,並能夠閱讀之間的延遲。

您將需要將此因素考慮在您的設計中。

+0

我可以設計任何明確的延遲嗎?我們在談論幾秒鐘?分鐘? –

+0

查看GAE/J文檔的「存儲數據」部分。這將告訴你如何解決或解決這個問題,並回答你的延遲問題。 –

0

作爲伊恩塞斯你必須處理這個延遲。以下是解決方案: 當您首次將您的User實例存儲在數據存儲中時,請使用makePersistent()方法,然後使用detachCopy()以獲取您也可以放入內存緩存的實例。您的fetchUserInfo()將首先從memcache中獲取用戶。如果未找到(== null),則從數據存儲中獲取。

相關問題