2011-11-14 23 views
1

私は、私は本番環境で奇妙な問題に直面してJBossキャッシュ。同時実行の問題

JBossCacheの「マラゲータ」3.2.0.GAを使用していますが、時々、正しく動作しないのJBossキャッシュに書き込みます。私は時々、単純なJavaアプリケーション

public static void testCache() { 
    Cache cache = new DefaultCacheFactory().createCache(false); 
    cache.create(); 
    cache.start(); 
    final Node node = cache.getRoot().addChild(Fqn.fromString("/child1")); 
    int threadsCount = 20; 
    final CyclicBarrier b = new CyclicBarrier(threadsCount); 
    for (int i = 0; i < threadsCount; i++) { 
     final long j = i; 
     new Thread(new Runnable() { 
      @Override 
      public void run() { 
       try { 
        b.await(); 
        String name = RandomGenerator.getRandomName(4); 
        node.put(j, name); 
        String nameFromCache = (String) node.get(j); 
        if (!name.equals(nameFromCache)) { 
         System.out.println("error"); 
        } 
       } catch (Exception e) { 
        e.printStackTrace(); 
       } 
      } 
     }).start(); 
    } 
} 

で、この状況を再現してみました、このテスト出力「エラー」、私は失敗しstatic void mainから実行します。 1/3が "エラー" msgを返します。単にnullを返します。私はすべてのマシンでそれを再現することはできません。

ヒント?

+0

アクセスする前にノードをロックする必要がありますか? – Fakrudeen

答えて

2

Jbossキャッシュが非同期である可能性があるので、コードは正常に見えます。キャッシュが更新されるときを保証するJavadocでは何も見ません。

多くの分散キャッシュ実装では、putオペレーションがワイヤに書き出され、キャッシュのローカルインスタンスでも、ローカルコールから直接ではなくインバウンドメッセージから更新されます。これにより、複数のマシンからの更新がネットワーク内のすべてのノードで正しい順序で処理されるように、キャッシュが更新を適切にシリアル化できるようになります。

キャッシュをLOCALに設定することを試してください。次のようなもの:

これが失敗しない場合、私は正しいと思われます。まだ失敗しても、LOCALモードのループバックネットワークスタックがまだ残っている可能性があるため、正しいかもしれません。

これが役に立ちます。

+0

デフォルトでは、キャッシュはローカルモードで実行され、jbossキャッシュのバグのようです。 – user12384512

+0

もう1つの方法は、スレッドのそれぞれにスピン・ループを入れて、ヌル応答が消えるまでの時間を確認することです。 – Gray