Deadlocks since activation of Shared Cache [message #1801531] |
Mon, 21 January 2019 16:53  |
Eclipse User |
|
|
|
Hello,
I configured shared cache on some of our entities and since then we are facing rare deadlocks happening just after getting this exception :
Exception [EclipseLink-2004] (Eclipse Persistence Services - 2.7.2.v20180622-f627448): org.eclipse.persistence.exceptions.ConcurrencyException|Exception Description: A signal was attempted before wait() on ConcurrencyManager. This normally means that an attempt was made to |commit or rollback a transaction before it was started, or to rollback a transaction twice.
at org.eclipse.persistence.exceptions.ConcurrencyException.signalAttemptedBeforeWait(ConcurrencyException.java:84)
at org.eclipse.persistence.internal.helper.ConcurrencyManager.releaseReadLock(ConcurrencyManager.java:473)
at org.eclipse.persistence.internal.identitymaps.CacheKey.releaseReadLock(CacheKey.java:475)
at org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.cloneAndRegisterObject(UnitOfWorkImpl.java:1088)
at org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.cloneAndRegisterObject(UnitOfWorkImpl.java:1002)
at org.eclipse.persistence.internal.sessions.UnitOfWorkIdentityMapAccessor.getAndCloneCacheKeyFromParent(UnitOfWorkIdentityMapAccessor.java:209)
at org.eclipse.persistence.internal.sessions.UnitOfWorkIdentityMapAccessor.getFromIdentityMap(UnitOfWorkIdentityMapAccessor.java:137)
at org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.registerExistingObject(UnitOfWorkImpl.java:4037)
at org.eclipse.persistence.queries.ObjectBuildingQuery.registerIndividualResult(ObjectBuildingQuery.java:460)
at org.eclipse.persistence.queries.ReadObjectQuery.registerResultInUnitOfWork(ReadObjectQuery.java:901)
at org.eclipse.persistence.queries.ObjectLevelReadQuery.checkEarlyReturn(ObjectLevelReadQuery.java:936)
at org.eclipse.persistence.mappings.OneToOneMapping.checkCacheForBatchKey(OneToOneMapping.java:835)
at org.eclipse.persistence.mappings.ForeignReferenceMapping.extractResultFromBatchQuery(ForeignReferenceMapping.java:535)
at org.eclipse.persistence.internal.indirection.BatchValueHolder.instantiate(BatchValueHolder.java:58)
at org.eclipse.persistence.internal.indirection.QueryBasedValueHolder.instantiate(QueryBasedValueHolder.java:120)
at org.eclipse.persistence.internal.indirection.DatabaseValueHolder.getValue(DatabaseValueHolder.java:95)
at org.eclipse.persistence.internal.indirection.UnitOfWorkValueHolder.instantiateImpl(UnitOfWorkValueHolder.java:173)
at org.eclipse.persistence.internal.indirection.UnitOfWorkValueHolder.instantiate(UnitOfWorkValueHolder.java:234)
at org.eclipse.persistence.internal.indirection.DatabaseValueHolder.getValue(DatabaseValueHolder.java:95)
at fr.ajacob.entity.PromotionTypeStore._persistence_get_store(PromotionTypeStore.java)
at fr.ajacob.entity.PromotionTypeStore.getStore(PromotionTypeStore.java:84)
at fr.ajacob.entity.fo.PromotionType.getPromotionTypeStore(PromotionType.java:255)
...
The 3 following entities seem to be related to this error, here is a summary of each of them (relevant parts) :
@Entity
public class PromotionType {
@Id
@Column
private Integer id;
(...)
@Noncacheable
@BatchFetch(value = BatchFetchType.IN)
@OneToMany(mappedBy = "promotionType", cascade = CascadeType.ALL, orphanRemoval = true)
private List<PromotionTypeStore> promotionTypeStores;
(...)
public PromotionTypeStore getPromotionTypeStore(Store store) {
for (PromotionTypeStore promotionTypeStore : this.getPromotionTypeStores()) {
if (promotionTypeStore.getStore().equals(store)) { // ==> line 255
return promotionTypeStore;
}
}
return null;
}
}
@Entity
@IdClass(PromotionTypeStorePK.class)
public class PromotionTypeStore {
@Id
@JoinColumn(name = "id_promotion_type", referencedColumnName = "id")
@ManyToOne(optional = false)
private PromotionType promotionType;
@BatchFetch(BatchFetchType.IN)
@Id
@JoinColumn(name = "id_store", referencedColumnName = "id")
@ManyToOne(optional = false, fetch = FetchType.LAZY)
private Store store;
(... other columns mapped ...)
public PromotionType getPromotionType() {
return promotionType;
}
public void setPromotionType(PromotionType promotionType) {
this.promotionType = promotionType;
}
public Store getStore() {
return store;
}
public void setStore(Store store) {
this.store = store;
}
}
@Entity
public class Store {
@Id
@Column(name = "id", nullable = false)
private Integer id;
(...)
}
They are all declared to be cacheable (shared cache)
I found this very interesting link https://wiki.eclipse.org/EclipseLink/FAQ/JPA#How_to_diagnose_and_resolve_hangs_and_deadlocks.3F giving good advice when using shared cache.
Now I wonder :
- Does my configuration look wrong ?
- The link says to declare relationships as LAZY, shall I declare PromotionType.promotionTypeStores to be LAZY ?
- I am using an @IdClass on PromotionTypeStore which is in the shared cache. Is this a bad idea ?
- Shall I declare PromotionTypeStore.promotionType and PromotionTypeStore.store @Noncacheable ?
- I manually call Cache.evict(<class>) on classes PromotionType and PromotionTypeStore, does the cache eviction need to be done in a transaction ?
The bug occurs once every 3 days, when it occurs all the threads get stuck and the server need to be restarted.
I've not yet managed to get a thread dump, I'll try to get one asap.
I tried to reproduce it in a development environment without success.
Thank you !
|
|
|
Re: Deadlocks since activation of Shared Cache [message #1801747 is a reply to message #1801531] |
Fri, 25 January 2019 10:09  |
Eclipse User |
|
|
|
How is the PromotionType instance you are calling getPromotionTypeStore on read in? Is it being cached and possibly reused by other threads?
Configuration looks fine to me, though I don't know what effect having the @Noncacheable annotation on the PromotionType. promotionTypeStores reference might play in this issue. If possible, you might try allowing it to be cacheable.
Best Regards,
Chris
|
|
|
Powered by
FUDForum. Page generated in 0.02940 seconds