【问题标题】:Google app engine JDO delayed data persistence谷歌应用引擎 JDO 延迟数据持久化
【发布时间】:2012-10-02 01:39:31
【问题描述】:

所有, 我有一个代码可以在数据存储中写入一些内容,并且在我调用检索刚刚写入数据存储的数据后立即进行。我的第二个电话总是失败!但是,如果我再次拨打电话,它可以正常工作并找到数据! 真的是连线!代码在 1.7.1 上运行良好,这在我升级到 1.7.2 后开始发生(不能 100% 确定,因为我同时还做了一些其他更改,但我想我也提到了) . 这是我编写数据的代码:

    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");
        }               
    });

    }

感谢任何帮助/指针

阿米尔

【问题讨论】:

  • 我几乎可以肯定问题出在 HRD 上,因为当我将其关闭时一切正常,但我真的很想利用 HRD,但也要强制数据为数据持久化后不久调用。
  • 感谢老兄的精彩评论!我知道我有什么,你要告诉我我错过了什么:)
  • “关闭 HDR”是什么意思?你说的是开发服务器吗?它的行为与“真实”数据存储区不同。

标签: java google-app-engine google-cloud-datastore jdo


【解决方案1】:

在写入 HRD 时,在持久化数据和能够读取数据之间存在延迟。

您需要在设计中考虑到这一点。

【讨论】:

  • 我可以围绕它设计任何定义的延迟吗?我们在谈论秒吗?分钟?
  • 查看 GAE/J 文档的“存储数据”部分。这将向您展示如何解决或解决此问题并回答您的延迟问题。
【解决方案2】:

正如 Ian 所说,您必须处理这种延迟。这是解决方案: 当您第一次将 User 实例存储在数据存储中时,请使用 makePersistent() 方法,然后使用 detachCopy() 来获取您也可以放入 memcache 中的实例。然后,您的 fetchUserInfo() 将首先从内存缓存中获取用户。如果未找到 (==null),则从数据存储中获取。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-04-20
    • 1970-01-01
    • 1970-01-01
    • 2013-10-13
    • 1970-01-01
    • 2011-07-05
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多