1

しばらくの間、問題を調査しています。だからコミュニティに聞いてください。私の目的は、特定の種類のすべてのエンティティを取得することであり、それらはすべて最新である必要があります。(現時点ではトランザクションの分離は考慮していません - ダーティ リードの可能性があります)

そのために GAE/J-JDO を使用します (tx.begin() の使用は単なる予防策です):

    PersistenceManager pm = PMF.get().getPersistenceManager();
    Transaction tx = pm.currentTransaction();
    Query q = pm.newQuery(TokenJdo.class);
    List<TokenJdo> tokenList = (List<TokenJdo>) q.execute();
    Collection<TokenJdo> res = Collections.unmodifiableCollection(tokenList);
    tx.commit();
    pm.close();
    for (TokenJdo t : tokenList) {
        log.info(t.getToken() + " - " + t.getCounter());
    }

これを行うと、古いエンティティが表示されます (リストをリクエストし、AppEngine コンソールに移動してエンティティを 1 つ変更し、もう一度リストをリクエストします)。そこで、DatastoreService を直接使用して次のデバッグ コードを作成しました。

    DatastoreService ds = DatastoreServiceFactory.getDatastoreService();
    com.google.appengine.api.datastore.Query gaeQuery = new com.google.appengine.api.datastore.Query(TokenJdo.class.getSimpleName());
    PreparedQuery pq = ds.prepare(gaeQuery);
    List<Entity> list = pq.asList(FetchOptions.Builder.withDefaults());
    for (Entity i : list) {
        log.info(i.getKey() + " - " + i.getProperties());
    }

1 つのリクエストで両方のコードを実行すると、次の出力が得られ、DatastoreService が返すものと比較して、JDO 経由のデータが古くなっていることが示されます。

I 2013-03-20 12:31:16.950 com.serverside.bl.TokenProviderJdo getAll: dummy - -999
I 2013-03-20 12:31:16.950 com.serverside.bl.TokenProviderJdo getAll: asd - 0
I 2013-03-20 12:31:16.951 com.serverside.bl.TokenProviderJdo getAll: dummy-aaa - -111
I 2013-03-20 12:31:16.957 com.serverside.bl.TokenProviderJdo logDSEntities: TokenJdo(7003) - {token=dummy, counter=-999}
I 2013-03-20 12:31:16.957 com.serverside.bl.TokenProviderJdo logDSEntities: TokenJdo(12001) - {token=asd, counter=0}
I 2013-03-20 12:31:16.957 com.serverside.bl.TokenProviderJdo logDSEntities: TokenJdo(13001) - {token=dummy-aaa, counter=-222}

どうやら (または私には見えるように)、JDO はある種の内部キャッシュ (L1 または L2 ですが、明示的には有効にしませんでした) を使用しています。JDO に「クリーン」読み取りを実行させるにはどうすればよいですか?

4

1 に答える 1

0

datanucleus何かをキャッシュしないようにするには、両方のキャッシュ レベルを無効にする必要があります。

datanucleus.cache.level1.type=none
datanucleus.cache.level2.mode=none

Queryまたは、 perまたは perのキャッシュを無効にすることもできます。 のメソッドまたはのメソッドPersistenceManagerを使用して、前述のキーを設定するだけです。QueryPersistenceManager

一方、オブジェクトを調べた後に使用する必要がある場合は、オブジェクトをデタッチする必要があります。それを使用するメソッドから戻る前に を閉じる必要があるため、これの技術的な理由についてはよくわかりませんPersistenceManagerが、すべてのキャッシュを無効にした後、検索したオブジェクトを使用する前に完全に切り離す必要があります。

于 2013-03-21T00:52:02.707 に答える