Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/hibernate/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Performance Ehcache过期和死锁_Performance_Hibernate_Spring Data Jpa_Ehcache - Fatal编程技术网

Performance Ehcache过期和死锁

Performance Ehcache过期和死锁,performance,hibernate,spring-data-jpa,ehcache,Performance,Hibernate,Spring Data Jpa,Ehcache,我使用的是Hibernate4.2.20和Ehcache2.6.6 我有2个实体和一个spring数据存储库,如下所示: @Entity @Inheritance(strategy = InheritanceType.TABLE_PER_CLASS) @Cache(region = "branch", usage = CacheConcurrencyStrategy.TRANSACTIONAL) public abstract class AbstractBranch{ ..... } @E

我使用的是Hibernate4.2.20和Ehcache2.6.6

我有2个实体和一个spring数据存储库,如下所示:

@Entity
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
@Cache(region = "branch", usage = CacheConcurrencyStrategy.TRANSACTIONAL)
public abstract class AbstractBranch{
 .....
}

@Entity
@Table(name = "branch")
public class Branch extends AbstractBranch {
}

public interface BranchRepository extends BaseRepository<Branch, UUID> {
     @QueryHints({ @QueryHint(name = "org.hibernate.cacheable", value = "true"), @QueryHint(name = "org.hibernate.cacheRegion", value = "branch") })
     Branch findByBranchId(String branchId);
}
我开始出现超时/死锁异常。看到stracktrace了吗

TimeoutManage I   WTRN0124I: When the timeout occurred the thread with which the transaction is, or was most recently, associated was Thread[WebContainer : 96,5,main]. The stack trace of this thread when the timeout occurred was: 
sun.misc.Unsafe.park(Native Method)
java.util.concurrent.locks.LockSupport.park(LockSupport.java:197)
java.util.concurrent.locks.AbstractQueuedSynchronizer.parkAndCheckInterrupt(AbstractQueuedSynchronizer.java:845)
java.util.concurrent.locks.AbstractQueuedSynchronizer.doAcquireShared(AbstractQueuedSynchronizer.java:975)
java.util.concurrent.locks.AbstractQueuedSynchronizer.acquireShared(AbstractQueuedSynchronizer.java:1293)
java.util.concurrent.locks.ReentrantReadWriteLock$ReadLock.lock(ReentrantReadWriteLock.java:742)
net.sf.ehcache.store.FrontEndCacheTier.containsKeyInMemory(FrontEndCacheTier.java:483)
net.sf.ehcache.transaction.AbstractTransactionStore.containsKeyInMemory(AbstractTransactionStore.java:187)
net.sf.ehcache.transaction.AbstractTransactionStore.containsKeyInMemory(AbstractTransactionStore.java:187)
net.sf.ehcache.Cache.searchInStoreWithStats(Cache.java:1941)
net.sf.ehcache.Cache.get(Cache.java:1584)
org.hibernate.cache.ehcache.internal.regions.EhcacheGeneralDataRegion.get(EhcacheGeneralDataRegion.java:74)
org.hibernate.cache.ehcache.internal.regions.EhcacheQueryResultsRegion.get(EhcacheQueryResultsRegion.java:39)
org.hibernate.cache.internal.StandardQueryCache.getCachedResults(StandardQueryCache.java:201)
org.hibernate.cache.internal.StandardQueryCache.get(StandardQueryCache.java:140)
org.hibernate.loader.Loader.getResultFromQueryCache(Loader.java:2477)
org.hibernate.loader.Loader.listUsingQueryCache(Loader.java:2385)
org.hibernate.loader.Loader.list(Loader.java:2358)
org.hibernate.loader.hql.QueryLoader.list(QueryLoader.java:495)
org.hibernate.hql.internal.ast.QueryTranslatorImpl.list(QueryTranslatorImpl.java:357)
org.hibernate.engine.query.spi.HQLQueryPlan.performList(HQLQueryPlan.java:198)
org.hibernate.internal.SessionImpl.list(SessionImpl.java:1230)
org.hibernate.internal.QueryImpl.list(QueryImpl.java:101)
org.hibernate.ejb.QueryImpl.getSingleResult(QueryImpl.java:287)
org.hibernate.ejb.criteria.CriteriaQueryCompiler$3.getSingleResult(CriteriaQueryCompiler.java:258)
org.springframework.data.jpa.repository.query.JpaQueryExecution$SingleEntityExecution.doExecute(JpaQueryExecution.java:206)
org.springframework.data.jpa.repository.query.JpaQueryExecution.execute(JpaQueryExecution.java:78)
org.springframework.data.jpa.repository.query.AbstractJpaQuery.doExecute(AbstractJpaQuery.java:100)
org.springframework.data.jpa.repository.query.AbstractJpaQuery.execute(AbstractJpaQuery.java:91)
org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.doInvoke(RepositoryFactorySupport.java:413)
org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.invoke(RepositoryFactorySupport.java:391)
org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:99)
org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:281)
org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:96)
org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:136)
org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
org.springframework.data.jpa.repository.support.CrudMethodMetadataPostProcessor$CrudMethodMetadataPopulatingMethodIntercceptor.invoke(CrudMethodMetadataPostProcessor.java:122)
org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:92)
org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:207)
com.sun.proxy.$Proxy125.findByBranchId(Unknown Source)
我已经发布了一个线程转储在 这显示了5个阻塞线程


有人知道如何防止这种情况发生吗?

根据EhCache文档,由于您在EhCache.xml中指定的XA事务模式,这些可能是“正常”超时异常

这种XA模式将在更新、删除或添加期间使用写锁。。。对于并发访问,这些锁会导致一些线程阻塞并出现死锁。最终,死锁线程超时(并引发异常),以避免陷入死锁状态


查看此页面,常见问题解答部分在“为什么某些线程经常超时并引发异常?”的问题下明确提到了这一点。

可以通过在LocalTransactionStore:put中设置断点来重现此问题。如果缓存已过期,则触发第一个请求,执行将在put中停止。然后触发第二个请求,该请求将到达remove并等待原始锁。重新启动第一个线程,就会出现死锁

以下是我认为它锁定的原因:

线程1:(堆栈锁定)
ReentrantReadWriteLock$NonfairSync(AbstractQueuedSynchronizer)。doAcquireShared(int)行:955
ReentrantReadWriteLock$NonfairSync(AbstractQueuedSynchronizer)。acquireShared(int)行:1282
ReentrantReadWriteLock$ReadLock.lock()行:731
MemoryOnlyStore(前端缓存层).isPinned(对象)行:111
LocalTransactionStore.put(元素)行:226
JtaLocalTransactionStore.put(元素)行:275

private void-doAcquireShared(int-arg)->int r=tryAcquireShared(arg);->else if(当前==getExclusiveOwnerThread())

线程2: (堆栈设置独占所有者线程)
java.util.concurrent.locks.AbstractOwnableSynchronizer.setExclusiveOwnerThread(AbstractOwnableSynchronizer.java:56)
java.util.concurrent.locks.ReentrantReadWriteLock$Sync.tryAcquire(ReentrantReadWriteLock.java:411)
java.util.concurrent.locks.AbstractQueuedSynchronizer.tryAcquireNanos(AbstractQueuedSynchronizer.java:1245)
java.util.concurrent.locks.ReentrantReadWriteLock$WriteLock.tryLock(ReentrantReadWriteLock.java:1115)
net.sf.ehcache.concurrent.ReadWriteLockSync.tryLock(ReadWriteLockSync.java:57)
net.sf.ehcache.Cache.tryremoviely(Cache.java:2103)
net.sf.ehcache.Cache.searchInStoreWithStats(Cache.java:1963)
net.sf.ehcache.Cache.get(Cache.java:1584)
org.hibernate.cache.ehcache.internal.strategy.TransactionalHcacheEntityRegionaccessStrategy.putFromLoad(TransactionalHcacheEntityRegionaccessStrategy.java:122)
org.hibernate.cache.ehcache.internal.nonstop.nonspawareentityregionaccessstrategy.putFromLoad(nonspawareentityregionaccessstrategy.java:195)

(堆栈锁定)
Unsafe.park(布尔值,长)行:不可用[本机方法]
锁支架。帕克纳(物体,长)线:226
ReentrantLock$NonfairSync(AbstractQueuedSynchronizer).doAcquireNanos(int,long)行:929
ReentrantLock$NonfairSync(AbstractQueuedSynchronizer).tryAcquireNanos(int,long)行:1245
ReentrantLock.tryLock(长,时间单位)行:445
ReadCommittedSoftLockImpl.tryLock(长)行:85
LocalTransactionStore.remove(对象)行:467
JtaLocalTransactionStore.remove(对象)行:371
Cache.removeInternal(对象,布尔,布尔,布尔,布尔)行:2334
Cache.tryremoviely立即(对象,布尔值)行:2117
Cache.searchInStoreWithStats(对象)行:1963 Cache.get(对象)行:1584
TransactionalCacheEntityRegionaccessStrategy.putFromLoad(对象,对象,长,对象,布尔值)行:122

第二个线程集ExclusiveOwnerThread作为:tryacquirenos->tryAcquire(arg)的一部分,然后作为:tryacquirenos->doacquirenos(arg,nanotimeout)的一部分停驻,因此,它不注册读或写锁,但将锁留给独占所有者集

从这一点开始,第一个线程中对ReadLock.lock的任何调用都将停止,因为tryAcquireShared失败,因为current==getExclusiveOwnerThread()为false,从而导致死锁

现在的问题是:为什么ReadLock.lock()会离开独占所有者线程集

更新:扩展堆栈我意识到事件发生在net.sf.ehcache.Cache的不同部分,并使用不同的类:

Cache.tryremoviely立即(Cache.java:2103)->ReadWriteLockSync.tryLock(ReadWriteLockSync.java:57)

Cache.tryremovieimmediately(Object,boolean)行:2117->(…)->ReentrantLock.tryLock(long,TimeUnit)

第一个设置独占所有者线程,并在tryAcquire中返回true

ReentrantReadWriteLock$Sync.tryAcquire
protected final boolean tryAcquire(整数获取){
/*
*演练:
*1.如果读取计数非零或写入计数非零
*而所有者是另一个线程,失败。
*2.如果计数将饱和,则失败。(这只能
*如果计数已非零,则发生。)
*3.否则,如果
*它要么是可重入获取,要么是
*队列策略允许。如果允许,请更新状态
*并设置所有者。
*/
线程当前=Thread.currentThread();
int c=getState();
int w=排他性账户(c);
如果(c!=0){
//(注意:如果c!=0且w=0,则共享计数!=0)
如果(w==0 | | current!=getExclusiveOwnerThread())
返回false;
if(w+独家帐户(收购)>最大计数)
抛出新的
branchRepository.findByBranchId(...).
TimeoutManage I   WTRN0124I: When the timeout occurred the thread with which the transaction is, or was most recently, associated was Thread[WebContainer : 96,5,main]. The stack trace of this thread when the timeout occurred was: 
sun.misc.Unsafe.park(Native Method)
java.util.concurrent.locks.LockSupport.park(LockSupport.java:197)
java.util.concurrent.locks.AbstractQueuedSynchronizer.parkAndCheckInterrupt(AbstractQueuedSynchronizer.java:845)
java.util.concurrent.locks.AbstractQueuedSynchronizer.doAcquireShared(AbstractQueuedSynchronizer.java:975)
java.util.concurrent.locks.AbstractQueuedSynchronizer.acquireShared(AbstractQueuedSynchronizer.java:1293)
java.util.concurrent.locks.ReentrantReadWriteLock$ReadLock.lock(ReentrantReadWriteLock.java:742)
net.sf.ehcache.store.FrontEndCacheTier.containsKeyInMemory(FrontEndCacheTier.java:483)
net.sf.ehcache.transaction.AbstractTransactionStore.containsKeyInMemory(AbstractTransactionStore.java:187)
net.sf.ehcache.transaction.AbstractTransactionStore.containsKeyInMemory(AbstractTransactionStore.java:187)
net.sf.ehcache.Cache.searchInStoreWithStats(Cache.java:1941)
net.sf.ehcache.Cache.get(Cache.java:1584)
org.hibernate.cache.ehcache.internal.regions.EhcacheGeneralDataRegion.get(EhcacheGeneralDataRegion.java:74)
org.hibernate.cache.ehcache.internal.regions.EhcacheQueryResultsRegion.get(EhcacheQueryResultsRegion.java:39)
org.hibernate.cache.internal.StandardQueryCache.getCachedResults(StandardQueryCache.java:201)
org.hibernate.cache.internal.StandardQueryCache.get(StandardQueryCache.java:140)
org.hibernate.loader.Loader.getResultFromQueryCache(Loader.java:2477)
org.hibernate.loader.Loader.listUsingQueryCache(Loader.java:2385)
org.hibernate.loader.Loader.list(Loader.java:2358)
org.hibernate.loader.hql.QueryLoader.list(QueryLoader.java:495)
org.hibernate.hql.internal.ast.QueryTranslatorImpl.list(QueryTranslatorImpl.java:357)
org.hibernate.engine.query.spi.HQLQueryPlan.performList(HQLQueryPlan.java:198)
org.hibernate.internal.SessionImpl.list(SessionImpl.java:1230)
org.hibernate.internal.QueryImpl.list(QueryImpl.java:101)
org.hibernate.ejb.QueryImpl.getSingleResult(QueryImpl.java:287)
org.hibernate.ejb.criteria.CriteriaQueryCompiler$3.getSingleResult(CriteriaQueryCompiler.java:258)
org.springframework.data.jpa.repository.query.JpaQueryExecution$SingleEntityExecution.doExecute(JpaQueryExecution.java:206)
org.springframework.data.jpa.repository.query.JpaQueryExecution.execute(JpaQueryExecution.java:78)
org.springframework.data.jpa.repository.query.AbstractJpaQuery.doExecute(AbstractJpaQuery.java:100)
org.springframework.data.jpa.repository.query.AbstractJpaQuery.execute(AbstractJpaQuery.java:91)
org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.doInvoke(RepositoryFactorySupport.java:413)
org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.invoke(RepositoryFactorySupport.java:391)
org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:99)
org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:281)
org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:96)
org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:136)
org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
org.springframework.data.jpa.repository.support.CrudMethodMetadataPostProcessor$CrudMethodMetadataPopulatingMethodIntercceptor.invoke(CrudMethodMetadataPostProcessor.java:122)
org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:92)
org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:207)
com.sun.proxy.$Proxy125.findByBranchId(Unknown Source)