0

すべて、データストアに何かを書き込むコードがあり、データストアに書き込んだばかりのデータを取得するための呼び出しを行った直後です。私の 2 回目の呼び出しは常に失敗します。ただし、もう一度呼び出しを行うと、正常に動作し、データが見つかります! 本当に有線です!コードは 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 エラーが発生し、2 回目の呼び出しで必要なデータが取得されます。

2 番目のコード セグメントは 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");
        }               
    });

    }

任意のヘルプ/ポインタをいただければ幸いです

アミール

4

2 に答える 2

1

HRD に書き込む場合、データが保持されてから読み取れるようになるまでに遅延があります。

これを設計に組み込む必要があります。

于 2012-10-02T16:17:03.400 に答える
0

Ian が言うように、この遅延に対処する必要があります。解決策は次のとおりです。最初に User インスタンスをデータ ストアに格納するときは、makePersistent() メソッドを使用してから、detachCopy() メソッドを使用して、memcache にも配置できるインスタンスを取得します。fetchUserInfo() は、最初に memcache からユーザーをフェッチします。見つからない場合 (==null)、データストアから取得します。

于 2013-01-20T10:33:00.143 に答える