2016-05-16 13 views
1

私はhibernate 2レベルキャッシュ(springで設定)を使用してHazelcastを操作していますが、最初のサーバは2番目のサーバに追い出しメッセージを送ります。第2サーバの追放タイムスタンプは実際の追放時間+ 1時間を含む。hibernate 2レベル追い出しを伴う分散キャッシュ

これにより、2番目のサーバーがキャッシュを失い、次の1時間または2番目のサーバーからのローカルキャッシュが追い出されるまで、DBへのクエリが実行されます。

1時間の間隔がcom.hazelcast.hibernate.HazelcastTimestamper

public static int getTimeout(HazelcastInstance instance, String regionName) { 
     try { 
      final MapConfig cfg = instance.getConfig().findMapConfig(regionName); 
      if (cfg.getTimeToLiveSeconds() > 0) { 
       // TTL in ms 
       return cfg.getTimeToLiveSeconds() * SEC_TO_MS; 
      } 
     } catch (UnsupportedOperationException e) { 
      // HazelcastInstance is instance of HazelcastClient. 
      Logger.getLogger(HazelcastTimestamper.class).finest(e); 
     } 
     return CacheEnvironment.getDefaultCacheTimeoutInMillis(); 
    } 

下による getTimeout機能に原因であるバージョン3.6.2での実装を見ながらgetDefaultCacheTimeoutInMillisはmapConfigながら360

を返します.getTimeToLiveSeconds()== 0

AbstractHazelcastRegionタイムアウトを取得

= 360×1000追い出しタイムアウトが実際に問題のキャッシュのタイムスタンプと

を得追い出しメッセージのタイムスタンプに追加される追い出しメッセージ中org.hibernate.cache.spi.UpdateTimestampsCache

public void preInvalidate(Serializable[] spaces, SessionImplementor session) throws CacheException { 
    final boolean stats = factory != null && factory.getStatistics().isStatisticsEnabled(); 

    **final Long ts = region.nextTimestamp() + region.getTimeout();** 

    for (Serializable space : spaces) { 
     if (DEBUG_ENABLED) { 
      LOG.debugf("Pre-invalidating space [%s], timestamp: %s", space, ts); 
     } 

     try { 
      session.getEventListenerManager().cachePutStart(); 

      //put() has nowait semantics, is this really appropriate? 
      //note that it needs to be async replication, never local or sync 
      region.put(space, ts); 
     } 
     finally { 
      session.getEventListenerManager().cachePutEnd(); 
     } 

     if (stats) { 
      factory.getStatisticsImplementor().updateTimestampsCachePut(); 
     } 
    } 
} 

this.timeout = HazelcastTimestamper.getTimeout(instance, regionName); 

私は何かを欠いているか、実際のロジックは非常に問題がありますか? 実際に期待どおりに動作している2番目のレベルのhibernateを使用している人は、実際に分散型サーバーの作業構成を持っていましたか?

答えて

1

Hibernateは、トランザクションの開始時にupdate/insertのためにpreInvalidateを呼び出し、トランザクションが完了するとUpdateTimestampsCache.invalidate(...)を呼び出します。これにより、lastUpdateの時刻が現在の時刻に戻ります。

トランザクションが実行されている間、影響を受けたスペースのクエリは最新ではなく、トランザクションが終了するとlastUpdate時間が設定され、将来の選択クエリがキャッシュされます。

org.hibernateのログをDEBUGに設定すると、これをログに記録できます。ログには、次のようになります。

DEBUG [UpdateTimestampsCache] Pre-invalidating space [<affected query spaces>], timestamp: <approximate current time + timeout> 
... your transaction here ... 
DEBUG [AbstractTransactionImpl] committing 
DEBUG [JdbcTransaction] committed JDBC Connection 
DEBUG [JdbcTransaction] re-enabling autocommit 
DEBUG [UpdateTimestampsCache] Invalidating space [<affected query spaces>], timestamp: <approximate current time> 

私はLASTUPDATEところ悪い状態でキャッシュを残して、時々この第二の「無効化スペースは、」トランザクションがコミットされていない場合は(可能なコーディングエラー)が起こるために失敗したことを観察しました(将来の時間+キャッシュのタイムアウト設定)に設定され、影響を受けるスペースのすべてのクエリがその時間に達するまで最新でないようにします。

関連する問題