2011-12-17 7 views
5

今日はGWTとJDOを初めて使用しています。 Eclipseでローカルデバッグモードで実行しています。私はすでに私のjdoconfig.xml<property name="datanucleus.appengine.datastoreReadConsistency" value="STRONG" />を設定App-Engine JDOの一貫した読み込みがうまくいかず、キャッシュできますか?

public Collection<MyObject> add(MyObject o) { 
PersistenceManager pm = PMF.get().getPersistenceManager(); 
try { 
    pm.makePersistent(o); 
    Query query = pm.newQuery(MyObject.class);// fetch all objects incl. o. But o only sometimes comes... 
List<MyObject> rs = (List<MyObject>) query.execute(); 
ArrayList<MyObject> list= new ArrayList<MyObject>(); 
for (MyObject r : rs) { 
    list.add(r); 
} 
return list; 
} finally { 
    pm.close(); 
} 
} 

私は、次のことを行います。私は設定で他のトランザクションのものをいくつか設定する必要がありますか?誰かが働いていたのですかjdoconfig.xml?それともどこか別の問題ですか?いくつかのキャッシングがありますか?

EDIT:私が試してみました物事:NontransactionalReadは/ PMF.get().getPersistenceManager()複数回

  • 使用してトランザクション/同じ呼び出し異なるPersistenceManagerかかわらを使用して偽
  • に書く設定

    • ignoreCache = true on PersistenceManager
    • flushおよび012私はここに、中央何かが欠けする必要があります

      <persistence-manager-factory name="transactions-optional"> 
      <property name="datanucleus.appengine.datastoreReadConsistency" value="STRONG" /> 
          <property name="javax.jdo.PersistenceManagerFactoryClass" 
           value="org.datanucleus.store.appengine.jdo.DatastoreJDOPersistenceManagerFactory"/> 
          <property name="javax.jdo.option.ConnectionURL" value="appengine"/> 
          <property name="javax.jdo.option.NontransactionalRead" value="true"/> 
          <property name="javax.jdo.option.NontransactionalWrite" value="true"/> 
          <property name="javax.jdo.option.RetainValues" value="true"/> 
          <property name="datanucleus.appengine.autoCreateDatastoreTxns" value="true"/> 
      </persistence-manager-factory> 
      

      すべてのアプローチが失敗するので...

      EDIT2:

    jdoconfig私は2つのトランザクションに仕事を分割すると、ログは言います書き込みトランザクションが終了してから、読み取りトランザクションが開始されます。しかし、それはちょうど拒否されたオブジェクトを見つけることはありません。それは常にLevel 1 Cache of type "weak" initialisedと言います。週は悪くて良い?

    これは、間違ったリクエストの約30%です...怠惰なクエリ読み込みの問題がありますか?

  • +1

    私も同じ問題に直面しています。私はいくつかのオブジェクトを私のアプリを通して追加しますが、結果に反映されないこともあります。 –

    +0

    オブジェクトはクエリ実行時にデータストアにありますか?明らかに、ログはそれをあなたに伝えます。これがGWTとどう関係しているのかは不明です... – DataNucleus

    +0

    ログはどこにありますか?GWTと何が関係していますか?それはGWTプロジェクトなので、たくさんあります。私はGWTとアプリエンジンとの間に明確な線を引くことはできないので、私はgoogleから来るすべてのGWTを呼び出します。そして、なぜキャッシュが非常に混乱して、同じインスタンスが書き込まれたデータを読み取ることさえできないのでしょうか?同じクライアントに対して常に一貫性のあるjdoconfig.xmlを投稿できますか? –

    答えて

    2

    Franzでは、JDOコンフィグレーションのデフォルトの読み取り整合性はSTRONGです。その方向にアプローチしようとしている場合は、どこでもあなたを導くことはありません。

    これは、遭遇したシナリオに似ていますが、コミットされたデータがクエリに返されなかったと思います。これは前述のように同時ではありませんが、コミットプロセスについて説明しています。

    http://code.google.com/appengine/articles/transaction_isolation.html

    また、別のアプローチは、エクステントを使用してクエリを実行し、私はあなたがテーブル内のすべてのレコードを引き出していると考えているので、それは、あなたが見ている特定のユースケースを解決するかどうかを調べることであろう。

    EDIT:

    あなたが言及したコードスニペットでは、それはテーブル全体を照会しているので。そして、それはあなたが必要なものであるならば、あなたは、エクステントを使用することができます...それを使用する 方法は、PersistenceManagerのシングルトンオブジェクトの

    Extent ext = getExtent(<Entity Class name>)

    を呼び出すことです。エクステントを繰り返すことができます

    このページのエクステントを調べて、ここでエクステントを検索してください。 http://code.google.com/appengine/docs/java/datastore/jdo/queries.html

    +0

    さて、コミットが返ってくると、変更が見えることは保証されていません(誰がそのような愚かな概念を発明するのでしょうか)。今質問は、どのように私はvisiblityを強制することができますか?または、where句でいくつかのトリックを行うことはできますか?テーブル全体をクエリすることについて何か言いましたか? –

    +1

    エクステントの使用に関するコメントを更新しました。また、JDOでのキャッシングの説明もあります。それは使用の可能性があります。 http://book.javanb.com/using-and-understanding-java-data-objects/LiB0046.html – Hrishikesh

    +0

    クラスのエクステントとクラスのクエリは全く同じものです。FWIW – DataNucleus

    2

    makePersistent()メソッドを呼び出すと、データストアに書き込まれません。 PersistenceManagerを閉じたり、変更をコミットしたりします。クエリを実行するときにこれを実行していないので、データストアからすべてのオブジェクトを取得していますが、まだ、makePersistentというオブジェクトをインクルードしていません。

    ここではオブジェクトの状態についての記事を読む: http://db.apache.org/jdo/state_transition.html

    この周りの2つの方法がありますが、あなたは(コミットがデータストアに書き込みを行うため、トランザクション内でこれを置くことができ念頭に取引上のGAE 5トランザクション/エンティティタイプの制限を保ちます)クエリを実行する前にコミットします。あなたはOでてmakePersistentを呼び出した後に永続マネージャを閉じて、その後にクエリを実行するために別のものを開くことができ

    public Collection<MyObject> add(MyObject o) { 
        PersistenceManager pm = PMF.get().getPersistenceManager(); 
        ArrayList<MyObject> list = null; 
        try { 
         Transaction tx=pm.currentTransaction(); 
         try { 
          tx.begin(); 
          pm.makePersistent(o); 
          tx.commit(); 
         } finally { 
          if (tx.isActive()) { 
           tx.rollback(); 
          } 
         } 
    
         Query query = pm.newQuery(MyObject.class); 
         List<MyObject> rs = (List<MyObject>) query.execute(); 
         ArrayList<MyObject> list = new ArrayList<MyObject>(); 
         for (MyObject r : rs) { 
          list.add(r); 
         } 
        } finally { 
         pm.close(); 
        } 
    
        return list; 
    } 
    

    またはトランザクションを使用して 例...。

    // Note that this only works assuming the makePersistent call is successful 
    public Collection<MyObject> add(MyObject o) { 
        PersistenceManager pm = PMF.get().getPersistenceManager(); 
        try { 
         pm.makePersistent(o); 
        } finally { 
         pm.close(); 
        } 
    
        pm = PMF.get().getPersistenceManager(); 
        ArrayList<MyObject> list = null; 
        try { 
    
         Query query = pm.newQuery(MyObject.class); 
         List<MyObject> rs = (List<MyObject>) query.execute(); 
         list= new ArrayList<MyObject>(); 
         for (MyObject r : rs) { 
          list.add(r); 
         } 
    
        } finally { 
         pm.close(); 
        } 
    
        return list; 
    } 
    

    注:私はもともとあなただけ返す前に結果リストにoを追加することができました。それはデータストアにoという文字列を書くのに問題があるため、これは賢明ではありません。返されたリストはデータストア内の実際のデータを反映しません。あなたがdatastoreReadPolicyをSTRONGに設定しているので、私が現在行っていること(トランザクションをコミットするか、pmを閉じて別のトランザクションを終了する)はうまくいくはずです。

    +2

    私は両方のアプローチを試してみました。トランザクション。時にはそれは動作し、時々そうではありませんが、これは真剣に台無しです。私はプロジェクトをきれいにし、jdk6にダウングレードしました。今はオプションがありません。コミット後もflushとconstancyCheckを呼び出すことさえできますが、すべて役に立ちません。データがデータストアに十分に速く到達しないことがあります。新しいオブジェクトを結果に手動で追加することで以前の考え方。私はそれをしましたが、時にはその値がまだ店舗にないため、後でリクエストしたときに問題が発生することがあります。ブラウザのリフレッシュはそのトリックを行います(ほとんど?)。 –

    +0

    あなたはどんな種類のキャッシングをしていますか?いくつかの種類のマップまたはMemcache APIを使用していますか? – Dave

    1

    同じ問題が発生しましたが、これは役に立ちませんでした。それはGoogleで "eclipseのjdoアプリエンジンの一貫性"のための最高の結果であるように思われるので、私は私のための修正を共有すると思った!

    私はいくつかの奇妙な振る舞いにつながったPersistenceManagerFactoryを複数のインスタンスで使用していました。この修正は、すべてのコードがアクセスするシングルトンを持つことです。これは実際にはGAEチュートリアルのdocumented correctlyですが、重要だと思います。

    アプリのPersistenceManager クラスのインスタンスを使用して、JDOと相互作用するのPersistenceManagerインスタンスを

    を取得します。このインスタンスは、 のメソッドをインスタンス化して呼び出し、PersistenceManagerFactoryクラスのインスタンスを呼び出します。工場では、 JDO設定を使用してPersistenceManagerインスタンスを作成します。

    PersistenceManagerFactoryインスタンスが初期化に時間がかかるので、 は、アプリケーションが1つのインスタンスを再利用する必要があります。 PersistenceManagerFactoryのインスタンスを管理するための簡単な方法は、以下のように、静的インスタンスをシングルトンラッパー クラスを作成することです:

    PMF.java

    import javax.jdo.JDOHelper; 
    import javax.jdo.PersistenceManagerFactory; 
    
        public final class PMF { 
         private static final PersistenceManagerFactory pmfInstance = 
          JDOHelper.getPersistenceManagerFactory("transactions-optional"); 
    
         private PMF() {} 
    
         public static PersistenceManagerFactory get() { 
          return pmfInstance; 
         } 
        } 
    
    +0

    これは他の多くの問題を解決しますが、これは元のポスターが直面する問題を解決しませんでした。また、devserver管理インターフェースはデータ変更を正しく反映しません。私がすべてをしばらく置いておくと、時には私は物事が持続し、利用可能になるのを見ます。それは何かが続いていると確信していますが、ランダムに感じます。 –

    関連する問題