2011-10-18 16 views
4

Ehcacheバージョン2.4.4とHibernate 3.5.5-FINALを使用しています。私はデバッグ環境で異常な状況が起こっている - Ehcacheがデッドロック状態になっているようだ。ここではスタックトレースの関連するビットです:Hibernate/Ehcacheデバッグのデバッグ

[email protected] daemon, prio=5, in group 'main', status: 'WAIT' 
     at sun.misc.Unsafe.park(Unsafe.java:-1) 
     at java.util.concurrent.locks.LockSupport.park(LockSupport.java:158) 
     at java.util.concurrent.locks.AbstractQueuedSynchronizer.parkAndCheckInterrupt(AbstractQueuedSynchronizer.java:811) 
     at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquireQueued(AbstractQueuedSynchronizer.java:842) 
     at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquire(AbstractQueuedSynchronizer.java:1178) 
     at java.util.concurrent.locks.ReentrantReadWriteLock$WriteLock.lock(ReentrantReadWriteLock.java:807) 
     at net.sf.ehcache.store.compound.Segment.put(Segment.java:427) 
     at net.sf.ehcache.store.compound.CompoundStore.put(CompoundStore.java:141) 
     at net.sf.ehcache.Cache.putInternal(Cache.java:1434) 
     at net.sf.ehcache.Cache.put(Cache.java:1367) 
     at net.sf.ehcache.Cache.put(Cache.java:1339) 
     at net.sf.ehcache.constructs.EhcacheDecoratorAdapter.put(EhcacheDecoratorAdapter.java:111) 
     at net.sf.ehcache.hibernate.regions.EhcacheTransactionalDataRegion.put(EhcacheTransactionalDataRegion.java:127) 
     at net.sf.ehcache.hibernate.strategy.NonStrictReadWriteEhcacheEntityRegionAccessStrategy.putFromLoad(NonStrictReadWriteEhcacheEntityRegionAccessStrategy.java:66) 
     at net.sf.ehcache.hibernate.nonstop.NonstopAwareEntityRegionAccessStrategy.putFromLoad(NonstopAwareEntityRegionAccessStrategy.java:180) 
     at org.hibernate.engine.TwoPhaseLoad.initializeEntity(TwoPhaseLoad.java:180) 
     at org.hibernate.loader.Loader.initializeEntitiesAndCollections(Loader.java:898) 
     at org.hibernate.loader.Loader.doQuery(Loader.java:773) 
     at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:270) 
     at org.hibernate.loader.Loader.loadEntity(Loader.java:1953) 
     at org.hibernate.loader.entity.AbstractEntityLoader.load(AbstractEntityLoader.java:86) 
     at org.hibernate.loader.entity.AbstractEntityLoader.load(AbstractEntityLoader.java:76) 
     at org.hibernate.persister.entity.AbstractEntityPersister.load(AbstractEntityPersister.java:3270) 
     at org.hibernate.event.def.DefaultLoadEventListener.loadFromDatasource(DefaultLoadEventListener.java:496) 
     at org.hibernate.event.def.DefaultLoadEventListener.doLoad(DefaultLoadEventListener.java:477) 
     at org.hibernate.event.def.DefaultLoadEventListener.load(DefaultLoadEventListener.java:227) 
     at org.hibernate.event.def.DefaultLoadEventListener.onLoad(DefaultLoadEventListener.java:147) 
     at org.hibernate.impl.SessionImpl.fireLoad(SessionImpl.java:1080) 
     at org.hibernate.impl.SessionImpl.immediateLoad(SessionImpl.java:1018) 
     at org.hibernate.proxy.AbstractLazyInitializer.initialize(AbstractLazyInitializer.java:176) 
     at org.hibernate.proxy.AbstractLazyInitializer.getImplementation(AbstractLazyInitializer.java:215) 
     at org.hibernate.proxy.pojo.javassist.JavassistLazyInitializer.invoke(JavassistLazyInitializer.java:191) 
     at vyre.content.items.ItemInfo_$$_javassist_87.equals(ItemInfo_$$_javassist_87.java:-1) 
     at org.hibernate.util.EqualsHelper.equals(EqualsHelper.java:33) 
     at org.hibernate.type.AbstractType.isEqual(AbstractType.java:132) 
     at org.hibernate.type.ComponentType.isEqual(ComponentType.java:153) 
     at org.hibernate.cache.CacheKey.equals(CacheKey.java:79) 
     at net.sf.ehcache.store.compound.Segment.containsKey(Segment.java:279) 
     at net.sf.ehcache.store.compound.CompoundStore.containsKey(CompoundStore.java:353) 
     at net.sf.ehcache.store.compound.impl.MemoryOnlyStore.containsKeyInMemory(MemoryOnlyStore.java:121) 
     at net.sf.ehcache.Cache.searchInStoreWithStats(Cache.java:1884) 
     at net.sf.ehcache.Cache.get(Cache.java:1549) 
     at net.sf.ehcache.constructs.EhcacheDecoratorAdapter.get(EhcacheDecoratorAdapter.java:75) 
     at net.sf.ehcache.hibernate.regions.EhcacheTransactionalDataRegion.get(EhcacheTransactionalDataRegion.java:105) 
     at net.sf.ehcache.hibernate.strategy.NonStrictReadWriteEhcacheEntityRegionAccessStrategy.get(NonStrictReadWriteEhcacheEntityRegionAccessStrategy.java:55) 
     at net.sf.ehcache.hibernate.nonstop.NonstopAwareEntityRegionAccessStrategy.get(NonstopAwareEntityRegionAccessStrategy.java:122) 
     at org.hibernate.event.def.DefaultLoadEventListener.loadFromSecondLevelCache(DefaultLoadEventListener.java:586) 
     at org.hibernate.event.def.DefaultLoadEventListener.doLoad(DefaultLoadEventListener.java:459) 
     at org.hibernate.event.def.DefaultLoadEventListener.load(DefaultLoadEventListener.java:227) 
     at org.hibernate.event.def.DefaultLoadEventListener.onLoad(DefaultLoadEventListener.java:147) 
     at org.hibernate.impl.SessionImpl.fireLoad(SessionImpl.java:1080) 
     at org.hibernate.impl.SessionImpl.immediateLoad(SessionImpl.java:1018) 
     at org.hibernate.proxy.AbstractLazyInitializer.initialize(AbstractLazyInitializer.java:176) 
     at org.hibernate.proxy.AbstractLazyInitializer.getImplementation(AbstractLazyInitializer.java:215) 
     at org.hibernate.proxy.pojo.javassist.JavassistLazyInitializer.invoke(JavassistLazyInitializer.java:191) 
     at vyre.content.items.Item_$$_javassist_102.getName(Item_$$_javassist_102.java:-1) 
     at sun.reflect.NativeMethodAccessorImpl.invoke0(NativeMethodAccessorImpl.java:-1) 
     at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) 
     at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) 
     at java.lang.reflect.Method.invoke(Method.java:597) 
     at org.apache.velocity.runtime.parser.node.PropertyExecutor.execute(PropertyExecutor.java:142) 
     at org.apache.velocity.util.introspection.UberspectImpl$VelGetterImpl.invoke(UberspectImpl.java:533) 
     at org.apache.velocity.runtime.parser.node.ASTIdentifier.execute(ASTIdentifier.java:198) 
     at org.apache.velocity.runtime.parser.node.ASTReference.execute(ASTReference.java:252) 
     at org.apache.velocity.runtime.parser.node.ASTReference.render(ASTReference.java:332) 
     at org.apache.velocity.runtime.parser.node.SimpleNode.render(SimpleNode.java:336) 
     at org.apache.velocity.runtime.RuntimeInstance.render(RuntimeInstance.java:1277) 
     at org.apache.velocity.runtime.RuntimeInstance.evaluate(RuntimeInstance.java:1216) 
     at org.apache.velocity.runtime.RuntimeInstance.evaluate(RuntimeInstance.java:1165) 
     at org.apache.velocity.app.Velocity.evaluate(Velocity.java:191) 
     at org.apache.jsp.WEB_002dINF.jsp.pub_005fmodule.taglibs.contentTemplate.search.itemLink_jsp._jspService(itemLink.jsp:36) 

    (...another hundred or so irrelevant stack trace fragments skipped...) 

これは私が状況を理解する方法です:

  • Apacheの速度が評価を行っていると、休止状態のプロキシオブジェクトに
  • を通過している場合、スタックの底が始まります
  • このオブジェクトが<cache usage="nonstrict-read-write"/>でキャッシュされ、複合キー
  • Hibernateがキャッシュ
  • 休止/ EhcacheのCHECからエンティティを取得しようとしていますオブジェクトのKSのequalness(注:「本当の」equalsメソッドが実行されることはありません)
  • 等しいチェックはfalseを返し、オブジェクトが、すぐに負荷が成功したとして、オブジェクトが中に配置された休止状態
  • によってロードされていますキャッシュ
  • デッドロック?

次のようにのように見えるの問題のコードスニペットは:

net.sf.ehcache.store.compound.Segment.put(Segment.java:427) 

423 Element put(Object key, int hash, Element element, boolean onlyIfAbsent) { 
424 boolean installed = false; 
425 Object encoded = create(key, element); 
426 
427 writeLock().lock(); 
428 try { 
429  // ensure capacity 
430  if (count + 1 > threshold) { 

私はencodedオブジェクトにアクセスすることができますが、writeLock()が既に取得されているので、全体のスレッドがスタックしているように見えます。これはEhcacheの内部構造について私が知っているように私の力が終わるところですSegment

これ以上デバッグする方法についてのヒントはありますか?残念ながら、少しでも自己整合的なテストケースを作成することは選択肢にはなりません。

これもまたEhcache forums pageに掲載されています。

ありがとうございます。

+0

jvisualvmを使用すると、ロックがいつ表示されるかを確認できます。これにより、より多くのアイデアが得られます。あなたはどんなプラットフォームで走っているのですか?私はAIXでこれまでと同様の問題(すべてのスレッドがブロックスレッドの証拠なしでブロックされていた)と戦ったが、パッチが見つからないことが原因であることが判明した – SirVaulterScoff

答えて

7

を開発しています。

理由:
デッドロックがキャッシュ内のオブジェクトの位置を特定しようとする試みが行われた同じスレッドから来ていた理由。スタックの一番下の部分では、Ehcacheは同じロックオブジェクトにreadLock().lock()writeLock().lock()を実行していました。これは明らかにno-noです。

どうしてですか? これは、キャッシュが別のオブジェクトを副作用としてロードしていて、別のオブジェクトが同じメモリセグメントで終了したため(同じReentrantLockを共有したため)、この問題が発生しました。ヒント:何百もの異なるエンティティタイプの容量を指定したくないのと同じキャッシュ領域を使用します。

どうしてですか? 私のHibernateマッピングのためにキャッシュキールックアップの不注意な読み込みが行われました。参照されていたオブジェクトは複合キーを持ち、別のオブジェクトを参照していました。その複合キーの一部がequalsメソッドで使用され、その負荷の原因となっていました。偶然にも、ロードされたオブジェクトも同じキャッシュセグメントに配置されようとし、デッドロックを引き起こしました。

レッスンはあなたのHibernateのマッピングに注意余分
を学びました。コンポジットキーをお持ちの場合は、<key-many-to-oneを使用しないでください。予期しない結果につながる可能性があります。私は多くの人が異なる種類のオブジェクトを異なるキャッシュ領域に配置するためにのみ、このことを認識していないと思いますが、不注意な負荷も悪いです。

すべてのクレジットは、これを見つけるのを手伝ってくれたテラコッタフォーラムからアレックスに行く。

+0

なぜ明らかにno-noをreadLock().lock()とwriteLock()。ライターはライターと他のライターの両方をブロックするために、読み取りロックと書き込みロックの両方を取得する必要はありませんか? – morten

+0

私は何が起こったのか分からなかった。同様の問題がありますが、休止状態はありません。キャッシュされたメソッドの1つが別のメソッドを呼び出すのが奇妙に見えますが、どのようにデッドロックが発生するのかわかりません。別のオブジェクトを読み込む際の問題は何ですか?どのようにしてデッドロックが発生しましたか? – morten

+1

これは6年前か7年前のことでしたので、これらのスレッドが違うかどうかにかかわらず、その詳細を覚えていないでしょう(ソースコードへのアクセス権もありません)。 https://stackoverflow.com/a/37087262/7345では、スレッドごとに問題が発生する可能性があることを示しています。 – mindas

0

JProfiler(完全に機能する評価版があります)を使用すると、現在のロッキンググラフを見ることができます。これは、java.util.concurrentロックをサポートし、ロックを持っている人と取得された場所を通知します。その情報を使用することで、問題の分析がより簡単になります。

免責事項:他の誰かがこの上でスリップし、Ehcacheのフォーラムでのポストが消えた場合私の会社は、念のために自分の質問に答えるJProfilerを

+0

kingoがありがとうございましたが、この場合デバッガはプロファイラよりもはるかに適切なツールです。私は、Ehcacheが最初に読み取りロックを取得してから、書き込みロックを取得しようとしていることを発見しました。問題はなぜHibernateがそれをこのように編成するのかです... – mindas